blob: e11cb225f557671a3ec0566b3bc0749373f16178 [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
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004Copyright 2012 Open Networking Foundation (ONF)
adminbae64d82013-08-01 10:50:15 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
Jon Hall7eb38402015-01-08 17:19:54 -080010TestON is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070014
Jon Hall7eb38402015-01-08 17:19:54 -080015TestON is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070019
Jon Hall7eb38402015-01-08 17:19:54 -080020You should have received a copy of the GNU General Public License
21along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
Jon Hallbe6dfc42015-01-12 17:37:25 -080023MininetCliDriver is the basic driver which will handle the Mininet functions
24
25Some functions rely on a modified version of Mininet. These functions
26should all be noted in the comments. To get this MN version run these commands
27from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080028 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080030 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080031 git pull
32
Jon Hall272a4db2015-01-12 17:43:48 -080033
34 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080035changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070036import pexpect
adminbae64d82013-08-01 10:50:15 -070037import re
38import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070039import types
kelvin-onlaba4074292015-07-09 15:19:49 -070040import os
Devin Lima7cfdbd2017-09-29 15:02:22 -070041import time
Jon Hall1ccf82c2014-10-15 14:55:16 -040042from math import pow
adminbae64d82013-08-01 10:50:15 -070043from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070044from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070045
Jon Hall7eb38402015-01-08 17:19:54 -080046
kelvin-onlab50907142015-04-01 13:37:45 -070047class MininetCliDriver( Emulator ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -070048
Jon Hall7eb38402015-01-08 17:19:54 -080049 """
50 MininetCliDriver is the basic driver which will handle
51 the Mininet functions"""
52 def __init__( self ):
Devin Limdc78e202017-06-09 18:30:07 -070053 super( MininetCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070054 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070056 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080057 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070058 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070059 # TODO: Refactor driver to use these everywhere
60 self.mnPrompt = "mininet>"
61 self.hostPrompt = "~#"
62 self.bashPrompt = "\$"
63 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070064 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070065
Jon Hall7eb38402015-01-08 17:19:54 -080066 def connect( self, **connectargs ):
67 """
68 Here the main is the TestON instance after creating
69 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080070 try:
71 for key in connectargs:
72 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070073 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080074 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070075 for key in self.options:
76 if key == "home":
77 self.home = self.options[ 'home' ]
78 break
79 if self.home is None or self.home == "":
80 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070081
82 try:
Jon Hall892818c2015-10-20 17:58:34 -070083 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070084 self.ip_address = os.getenv( str( self.ip_address ) )
85 else:
86 main.log.info( self.name +
87 ": Trying to connect to " +
88 self.ip_address )
89
90 except KeyError:
91 main.log.info( "Invalid host name," +
92 " connecting to local host instead" )
93 self.ip_address = 'localhost'
94 except Exception as inst:
95 main.log.error( "Uncaught exception: " + str( inst ) )
96
kelvin-onlaba1484582015-02-02 15:46:20 -080097 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070098 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080099 self ).connect(
100 user_name=self.user_name,
101 ip_address=self.ip_address,
102 port=None,
103 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800104
kelvin-onlaba1484582015-02-02 15:46:20 -0800105 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800106 main.log.info( "Connection successful to the host " +
107 self.user_name +
108 "@" +
109 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800110 return main.TRUE
111 else:
112 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800113 self.user_name +
114 "@" +
115 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800116 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800117 return main.FALSE
118 except pexpect.EOF:
119 main.log.error( self.name + ": EOF exception found" )
120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700121 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800122 except Exception:
123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700124 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800125
kelvin-onlab10e8d392015-06-03 13:53:45 -0700126 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800127 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700128 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000129 Starts Mininet accepts a topology(.py) file and/or an optional
kelvin-onlabf512e942015-06-08 19:42:59 -0700130 argument, to start the mininet, as a parameter.
131 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700132 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700133 Options:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000134 topoFile = file path for topology file (.py)
kelvin-onlabf512e942015-06-08 19:42:59 -0700135 args = extra option added when starting the topology from the file
136 mnCmd = Mininet command use to start topology
137 Returns:
138 main.TRUE if the mininet starts successfully, main.FALSE
139 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800140 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700141 try:
142 if self.handle:
143 # make sure old networks are cleaned up
144 main.log.info( self.name +
145 ": Clearing any residual state or processes" )
146 self.handle.sendline( "sudo mn -c" )
147 i = self.handle.expect( [ 'password\sfor\s',
148 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800149 pexpect.EOF,
150 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700151 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800152 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700153 # Sudo asking for password
154 main.log.info( self.name + ": Sending sudo password" )
155 self.handle.sendline( self.pwd )
Jon Hall173f2a02018-01-11 13:56:37 -0800156 i = self.handle.expect( [ '%s:' % self.user_name,
Devin Limdc78e202017-06-09 18:30:07 -0700157 self.prompt,
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700158 pexpect.EOF,
159 pexpect.TIMEOUT ],
160 timeout )
161 if i == 1:
162 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700163 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700164 main.log.error( self.name + ": Connection terminated" )
165 elif i == 3: # timeout
166 main.log.error( self.name + ": Something while cleaning " +
167 "Mininet took too long... " )
168 # Craft the string to start mininet
169 cmdString = "sudo "
170 if not mnCmd:
171 if topoFile is None or topoFile == '': # If no file is given
172 main.log.info( self.name + ": building fresh Mininet" )
173 cmdString += "mn "
174 if args is None or args == '':
175 # If no args given, use args from .topo file
176 args = self.options[ 'arg1' ] +\
177 " " + self.options[ 'arg2' ] +\
178 " --mac --controller " +\
179 self.options[ 'controller' ] + " " +\
180 self.options[ 'arg3' ]
181 else: # else only use given args
182 pass
183 # TODO: allow use of topo args and method args?
184 else: # Use given topology file
185 main.log.info(
186 "Starting Mininet from topo file " +
187 topoFile )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700188 cmdString += "-E python " + topoFile + " "
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700189 if args is None:
190 args = ''
191 # TODO: allow use of args from .topo file?
192 cmdString += args
193 else:
194 main.log.info( "Starting Mininet topology using '" + mnCmd +
195 "' command" )
196 cmdString += mnCmd
197 # Send the command and check if network started
198 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700199 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700200 main.log.info( "Sending '" + cmdString + "' to " + self.name )
201 self.handle.sendline( cmdString )
Devin Lima7cfdbd2017-09-29 15:02:22 -0700202 startTime = time.time()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700203 while True:
204 i = self.handle.expect( [ 'mininet>',
205 'Exception',
206 '\*\*\*',
207 pexpect.EOF,
Jon Hallab611372018-02-21 15:26:05 -0800208 pexpect.TIMEOUT,
209 "No such file or directory"],
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700210 timeout )
211 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -0700212 main.log.info( self.name + ": Mininet built\nTime Took : " + str( time.time() - startTime ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700213 return main.TRUE
214 elif i == 1:
215 response = str( self.handle.before +
216 self.handle.after )
Devin Limdc78e202017-06-09 18:30:07 -0700217 self.handle.expect( self.prompt )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700218 response += str( self.handle.before +
219 self.handle.after )
220 main.log.error(
221 self.name +
222 ": Launching Mininet failed: " + response )
223 return main.FALSE
224 elif i == 2:
225 self.handle.expect( [ "\n",
226 pexpect.EOF,
227 pexpect.TIMEOUT ],
228 timeout )
229 main.log.info( self.handle.before )
230 elif i == 3:
231 main.log.error( self.name + ": Connection timeout" )
232 return main.FALSE
233 elif i == 4: # timeout
234 main.log.error(
235 self.name +
236 ": Something took too long... " )
237 return main.FALSE
Jon Hallab611372018-02-21 15:26:05 -0800238 elif i == 5:
239 main.log.error( self.name + ": " + self.handle.before + self.handle.after )
240 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700241 # Why did we hit this part?
242 main.log.error( "startNet did not return correctly" )
243 return main.FASLE
244 else: # if no handle
245 main.log.error( self.name + ": Connection failed to the host " +
246 self.user_name + "@" + self.ip_address )
247 main.log.error( self.name + ": Failed to connect to the Mininet" )
248 return main.FALSE
249 except pexpect.TIMEOUT:
250 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
251 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700252 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700253 except pexpect.EOF:
254 main.log.error( self.name + ": EOF exception found" )
255 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700256 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700257 except Exception:
258 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700259 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800260
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800261 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700262 try:
263 if topoType == 'tree':
264 # In tree topology, if fanout arg is not given, by default it is 2
265 if fanout is None:
266 fanout = 2
267 k = 0
268 count = 0
269 while( k <= depth - 1 ):
270 count = count + pow( fanout, k )
271 k = k + 1
272 numSwitches = count
273 while( k <= depth - 2 ):
274 # depth-2 gives you only core links and not considering
275 # edge links as seen by ONOS. If all the links including
276 # edge links are required, do depth-1
277 count = count + pow( fanout, k )
278 k = k + 1
279 numLinks = count * fanout
280 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
281 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800282
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700283 elif topoType == 'linear':
284 # In linear topology, if fanout or numHostsPerSw is not given,
285 # by default it is 1
286 if fanout is None:
287 fanout = 1
288 numSwitches = depth
289 numHostsPerSw = fanout
290 totalNumHosts = numSwitches * numHostsPerSw
291 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hallab611372018-02-21 15:26:05 -0800292 main.log.debug( "num_switches for %s(%d,%d) = %d and links=%d" %
293 ( topoType, depth, fanout, numSwitches, numLinks ) )
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700294 topoDict = { "num_switches": int( numSwitches ),
295 "num_corelinks": int( numLinks ) }
296 return topoDict
297 except Exception:
298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700299 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400300
kelvin-onlabd3b64892015-01-20 13:26:24 -0800301 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700302 """
303 Calculate the number of switches and links in a topo."""
304 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700305 try:
306 argList = self.options[ 'arg1' ].split( "," )
307 topoArgList = argList[ 0 ].split( " " )
308 argList = map( int, argList[ 1: ] )
309 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700310
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700311 topoDict = self.numSwitchesNlinks( *topoArgList )
312 return topoDict
313 except Exception:
314 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700315 main.cleanAndExit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400316
GlennRCf07c44a2015-09-18 13:33:46 -0700317 def pingall( self, protocol="IPv4", timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800318 """
319 Verifies the reachability of the hosts using pingall command.
320 Optional parameter timeout allows you to specify how long to
321 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700322 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700323 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700324 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700325 ping
326 acceptableFailed - Set the number of acceptable failed pings for the
327 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800328 Returns:
329 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700330 otherwise main.FALSE
331 """
332 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700333 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700334 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700335 if self.handle:
336 main.log.info(
337 self.name +
338 ": Checking reachabilty to the hosts using pingall" )
339 response = ""
340 failedPings = 0
341 returnValue = main.TRUE
GlennRCf07c44a2015-09-18 13:33:46 -0700342 cmd = "pingall"
343 if protocol == "IPv6":
344 cmd = "py net.pingAll6()"
345 self.handle.sendline( cmd )
Jon Hall390696c2015-05-05 17:13:41 -0700346 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700347 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700348 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700349 pexpect.EOF,
350 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700351 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700352 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700353 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700354 response += self.handle.before
355 break
356 elif i == 1:
357 response += self.handle.before + self.handle.after
358 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700359 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700360 returnValue = main.FALSE
361 if shortCircuit:
362 main.log.error( self.name +
363 ": Aborting pingall - "
364 + str( failedPings ) +
365 " pings failed" )
366 break
Jon Hall390696c2015-05-05 17:13:41 -0700367 if ( time.time() - startTime ) > timeout:
368 returnValue = main.FALSE
369 main.log.error( self.name +
370 ": Aborting pingall - " +
371 "Function took too long " )
372 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700373 elif i == 2:
374 main.log.error( self.name +
375 ": EOF exception found" )
376 main.log.error( self.name + ": " +
377 self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700378 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700379 elif i == 3:
380 response += self.handle.before
381 main.log.error( self.name +
382 ": TIMEOUT exception found" )
383 main.log.error( self.name +
384 ": " +
385 str( response ) )
386 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800387 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700388 self.handle.expect( "Interrupt" )
389 self.handle.expect( "mininet>" )
390 break
391 pattern = "Results\:"
392 main.log.info( "Pingall output: " + str( response ) )
393 if re.search( pattern, response ):
394 main.log.info( self.name + ": Pingall finished with "
395 + str( failedPings ) + " failed pings" )
396 return returnValue
397 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700398 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800399 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700400 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700401 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700402 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700403 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700404 main.log.error( self.name + ": Connection failed to the host" )
Devin Lim44075962017-08-11 10:56:37 -0700405 main.cleanAndExit()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700406 except pexpect.TIMEOUT:
407 if response:
408 main.log.info( "Pingall output: " + str( response ) )
409 main.log.error( self.name + ": pexpect.TIMEOUT found" )
410 return main.FALSE
411 except pexpect.EOF:
412 main.log.error( self.name + ": EOF exception found" )
413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700414 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -0700415
Jon Hall7eb38402015-01-08 17:19:54 -0800416 def fpingHost( self, **pingParams ):
417 """
418 Uses the fping package for faster pinging...
419 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700420 try:
421 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
422 command = args[ "SRC" ] + \
423 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
424 self.handle.sendline( command )
425 self.handle.expect(
426 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
427 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
428 response = self.handle.before
429 if re.search( ":\s-", response ):
430 main.log.info( self.name + ": Ping fail" )
431 return main.FALSE
432 elif re.search( ":\s\d{1,2}\.\d\d", response ):
433 main.log.info( self.name + ": Ping good!" )
434 return main.TRUE
435 main.log.info( self.name + ": Install fping on mininet machine... " )
436 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700437 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700438 except Exception:
439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700440 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700441
Jon Hall3b489db2015-10-05 14:38:37 -0700442 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400443 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700444 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700445
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400446 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700447 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700448
449 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400450 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700451
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400452 Returns main.FALSE if one or more of hosts specified
453 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700454 wait = int( wait )
455 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400456
457 try:
458 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700459
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400460 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700461 pingResponse = "IPv4 ping across specified hosts\n"
462 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400463 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700464 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400465 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700466 pingList = hostList[ :listIndex ] + \
467 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700468
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700469 pingResponse += str( str( host ) + " -> " )
GlennRCd10d3cc2015-09-24 12:47:16 -0700470
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400471 for temp in pingList:
472 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700473 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700474 self.handle.sendline( pingCmd )
475 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400476 response = self.handle.before
477 if re.search( ',\s0\%\spacket\sloss', response ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700478 pingResponse += str( " h" + str( temp[ 1: ] ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400479 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700480 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400481 # One of the host to host pair is unreachable
482 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700483 failedPings += 1
You Wang11f9ead2018-03-21 14:34:59 -0700484 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
GlennRCd10d3cc2015-09-24 12:47:16 -0700485 pingResponse += "\n"
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700486 main.log.info( pingResponse + "Failed pings: " + str( failedPings ) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700487 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700488 except pexpect.TIMEOUT:
489 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800490 response = self.handle.before
491 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700492 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800493 self.handle.expect( "Interrupt" )
494 response += self.handle.before + self.handle.after
495 self.handle.expect( "mininet>" )
496 response += self.handle.before + self.handle.after
497 main.log.debug( response )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700498 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400499 except pexpect.EOF:
500 main.log.error( self.name + ": EOF exception found" )
501 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700502 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700503 except Exception:
504 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700505 main.cleanAndExit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400506
You Wangf19d9f42018-02-23 16:34:19 -0800507 def pingIpv6Hosts( self, hostList, wait=1, acceptableFailed=0 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700508 """
You Wangf19d9f42018-02-23 16:34:19 -0800509 IPv6 ping all hosts in hostList.
510
511 acceptableFailed: max number of acceptable failed pings
Hari Krishna9592fc82015-07-31 15:11:15 -0700512
Jon Hall3b489db2015-10-05 14:38:37 -0700513 Returns main.TRUE if all hosts specified can reach each other
Jon Hall3b489db2015-10-05 14:38:37 -0700514 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700515 """
516 try:
517 main.log.info( "Testing reachability between specified IPv6 hosts" )
518 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700519 wait = int( wait )
520 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700521 pingResponse = "IPv6 Pingall output:\n"
You Wangf19d9f42018-02-23 16:34:19 -0800522 failedPingsTotal = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700523 for host in hostList:
524 listIndex = hostList.index( host )
525 # List of hosts to ping other than itself
526 pingList = hostList[ :listIndex ] + \
527 hostList[ ( listIndex + 1 ): ]
528
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700529 pingResponse += str( str( host ) + " -> " )
GlennRC2cf7d952015-09-11 16:32:13 -0700530
Hari Krishna9592fc82015-07-31 15:11:15 -0700531 for temp in pingList:
532 # Current host pings all other hosts specified
You Wangf19d9f42018-02-23 16:34:19 -0800533 failedPings = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700534 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
You Wangf19d9f42018-02-23 16:34:19 -0800535 while failedPings <= acceptableFailed:
536 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
537 self.handle.sendline( pingCmd )
538 self.handle.expect( "mininet>", timeout=wait + 1 )
539 response = self.handle.before
540 if re.search( ',\s0\%\spacket\sloss', response ):
You Wangba231e72018-03-01 13:18:21 -0800541 pingResponse += " " + str( temp )
542 break
543 else:
544 failedPings += 1
545 time.sleep(1)
546 if failedPings > acceptableFailed:
547 # One of the host to host pair is unreachable
548 pingResponse += " X"
549 isReachable = main.FALSE
550 failedPingsTotal += 1
You Wang11f9ead2018-03-21 14:34:59 -0700551 main.log.warn( "Cannot ping between {} and {}".format( host, temp ) )
You Wangba231e72018-03-01 13:18:21 -0800552 pingResponse += "\n"
553 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
554 return isReachable
555
556 except pexpect.TIMEOUT:
557 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800558 response = self.handle.before
559 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700560 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800561 self.handle.expect( "Interrupt" )
562 response += self.handle.before + self.handle.after
563 self.handle.expect( "mininet>" )
564 response += self.handle.before + self.handle.after
565 main.log.debug( response )
You Wangba231e72018-03-01 13:18:21 -0800566 return main.FALSE
567 except pexpect.EOF:
568 main.log.error( self.name + ": EOF exception found" )
569 main.log.error( self.name + ": " + self.handle.before )
570 main.cleanAndExit()
571 except Exception:
572 main.log.exception( self.name + ": Uncaught exception!" )
573 main.cleanAndExit()
574
575 def pingallHostsUnidirectional( self, srcList, dstList, ipv6=False, wait=1, acceptableFailed=0 ):
576 """
577 Verify ping from each host in srcList to each host in dstList
578
579 acceptableFailed: max number of acceptable failed pings
580
581 Returns main.TRUE if all src hosts can reach all dst hosts
582 Returns main.FALSE if one or more of src hosts cannot reach one or more of dst hosts
583 """
584 try:
585 main.log.info( "Verifying ping from each src host to each dst host" )
586 isReachable = main.TRUE
587 wait = int( wait )
588 cmd = " ping" + ("6" if ipv6 else "") + " -c 1 -i 1 -W " + str( wait ) + " "
589 pingResponse = "Ping output:\n"
590 failedPingsTotal = 0
591 for host in srcList:
592 pingResponse += str( str( host ) + " -> " )
593 for temp in dstList:
594 failedPings = 0
595 if ipv6:
596 pingCmd = str( host ) + cmd + str( self.getIPAddress( temp, proto='IPv6' ) )
597 else:
598 pingCmd = str( host ) + cmd + str( temp )
599 while failedPings <= acceptableFailed:
600 main.log.debug( "Pinging from " + str( host ) + " to " + str( temp ) )
601 self.handle.sendline( pingCmd )
602 self.handle.expect( "mininet>", timeout=wait + 1 )
603 response = self.handle.before
604 if re.search( ',\s0\%\spacket\sloss', response ):
605 pingResponse += " " + str( temp )
You Wangf19d9f42018-02-23 16:34:19 -0800606 break
607 else:
608 failedPings += 1
609 time.sleep(1)
610 if failedPings > acceptableFailed:
Hari Krishna9592fc82015-07-31 15:11:15 -0700611 # One of the host to host pair is unreachable
You Wangf19d9f42018-02-23 16:34:19 -0800612 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700613 isReachable = main.FALSE
You Wangf19d9f42018-02-23 16:34:19 -0800614 failedPingsTotal += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700615 pingResponse += "\n"
You Wangf19d9f42018-02-23 16:34:19 -0800616 main.log.info( pingResponse + "Failed pings: " + str( failedPingsTotal ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700617 return isReachable
618
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700619 except pexpect.TIMEOUT:
620 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800621 response = self.handle.before
622 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700623 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800624 self.handle.expect( "Interrupt" )
625 response += self.handle.before + self.handle.after
626 self.handle.expect( "mininet>" )
627 response += self.handle.before + self.handle.after
628 main.log.debug( response )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700629 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700630 except pexpect.EOF:
631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700633 main.cleanAndExit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700634 except Exception:
635 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700636 main.cleanAndExit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700637
Jon Hall7eb38402015-01-08 17:19:54 -0800638 def pingHost( self, **pingParams ):
639 """
Jon Hall3b489db2015-10-05 14:38:37 -0700640 Ping from one mininet host to another
641 Currently the only supported Params: SRC, TARGET, and WAIT
642 """
643 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700644 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700645 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800646 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700647 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700648 try:
Jon Hall61282e32015-03-19 11:34:11 -0700649 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800650 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700651 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
652 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700653 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800654 main.log.error(
655 self.name +
656 ": timeout when waiting for response from mininet" )
657 main.log.error( "response: " + str( self.handle.before ) )
658 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700659 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800660 main.log.error(
661 self.name +
662 ": timeout when waiting for response from mininet" )
663 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700664 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700665 if re.search( ',\s0\%\spacket\sloss', response ):
666 main.log.info( self.name + ": no packets lost, host is reachable" )
667 return main.TRUE
668 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800669 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700670 self.name +
671 ": PACKET LOST, HOST IS NOT REACHABLE" )
672 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800673 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800674 main.log.error( self.name + ": EOF exception found" )
675 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700676 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700677 except Exception:
678 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700679 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700680
681 def ping6pair( self, **pingParams ):
682 """
GlennRC2cf7d952015-09-11 16:32:13 -0700683 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700684 Currently the only supported Params are: SRC, TARGET, and WAIT
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000685 FLOWLABEL and -I (src interface) will be added later after running some tests.
Hari Krishna012a1c12015-08-25 14:23:58 -0700686 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
687 """
Jon Hall3b489db2015-10-05 14:38:37 -0700688 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700689 wait = args[ 'WAIT' ]
Jon Hall3b489db2015-10-05 14:38:37 -0700690 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530691 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700692 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700693 try:
694 main.log.info( "Sending: " + command )
695 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700696 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
697 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700698 if i == 1:
699 main.log.error(
700 self.name +
701 ": timeout when waiting for response from mininet" )
702 main.log.error( "response: " + str( self.handle.before ) )
703 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
704 if i == 1:
705 main.log.error(
706 self.name +
707 ": timeout when waiting for response from mininet" )
708 main.log.error( "response: " + str( self.handle.before ) )
709 response = self.handle.before
710 main.log.info( self.name + ": Ping Response: " + response )
711 if re.search( ',\s0\%\spacket\sloss', response ):
712 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700713 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700714 else:
alisone4121a92016-11-22 16:31:36 -0800715 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700716 self.name +
717 ": PACKET LOST, HOST IS NOT REACHABLE" )
718 return main.FALSE
Hari Krishna012a1c12015-08-25 14:23:58 -0700719 except pexpect.EOF:
720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700722 main.cleanAndExit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700723 except Exception:
724 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700725 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800726
You Wangdb927a52016-02-26 11:03:28 -0800727 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
728 """
729 Description:
730 Ping a set of destination host from host CLI.
731 Logging into a Mininet host CLI is required before calling this funtion.
732 Params:
733 dstIPList is a list of destination ip addresses
734 Returns:
735 main.TRUE if the destination host is reachable
736 main.FALSE otherwise
737 """
738 isReachable = main.TRUE
739 wait = int( wait )
740 cmd = "ping"
741 if IPv6:
742 cmd = cmd + "6"
743 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
744 try:
745 for dstIP in dstIPList:
746 pingCmd = cmd + " " + dstIP
747 self.handle.sendline( pingCmd )
748 i = self.handle.expect( [ self.hostPrompt,
749 '\*\*\* Unknown command: ' + pingCmd,
750 pexpect.TIMEOUT ],
751 timeout=wait + 1 )
752 if i == 0:
753 response = self.handle.before
754 if not re.search( ',\s0\%\spacket\sloss', response ):
755 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
756 isReachable = main.FALSE
757 elif i == 1:
758 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
Devin Lim44075962017-08-11 10:56:37 -0700759 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800760 elif i == 2:
761 main.log.error( self.name + ": timeout when waiting for response" )
762 isReachable = main.FALSE
763 else:
764 main.log.error( self.name + ": unknown response: " + self.handle.before )
765 isReachable = main.FALSE
766 except pexpect.TIMEOUT:
767 main.log.exception( self.name + ": TIMEOUT exception" )
Jon Hall3c910162018-03-07 14:42:16 -0800768 response = self.handle.before
769 # NOTE: Send ctrl-c to make sure command is stopped
Jon Hall2c5ac942018-03-23 11:26:54 -0700770 self.handle.send( "\x03" )
Jon Hall3c910162018-03-07 14:42:16 -0800771 self.handle.expect( "Interrupt" )
772 response += self.handle.before + self.handle.after
773 self.handle.expect( "mininet>" )
774 response += self.handle.before + self.handle.after
775 main.log.debug( response )
You Wangdb927a52016-02-26 11:03:28 -0800776 isReachable = main.FALSE
777 except pexpect.EOF:
778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700780 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800781 except Exception:
782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700783 main.cleanAndExit()
You Wangdb927a52016-02-26 11:03:28 -0800784 return isReachable
785
Jon Hall7eb38402015-01-08 17:19:54 -0800786 def checkIP( self, host ):
787 """
788 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700789 try:
790 if self.handle:
791 try:
792 response = self.execute(
793 cmd=host +
794 " ifconfig",
795 prompt="mininet>",
796 timeout=10 )
797 except pexpect.EOF:
798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700800 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700801
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700802 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
803 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
804 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
805 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
806 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
807 "[0-9]|25[0-5]|[0-9]{1,2})"
808 # pattern = "inet addr:10.0.0.6"
809 if re.search( pattern, response ):
810 main.log.info( self.name + ": Host Ip configured properly" )
811 return main.TRUE
812 else:
813 main.log.error( self.name + ": Host IP not found" )
814 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700815 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700816 main.log.error( self.name + ": Connection failed to the host" )
817 except Exception:
818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700819 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800820
Jon Hall7eb38402015-01-08 17:19:54 -0800821 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800822 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700823 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800824 response = self.execute(
825 cmd="h1 /usr/sbin/sshd -D&",
826 prompt="mininet>",
827 timeout=10 )
828 response = self.execute(
829 cmd="h4 /usr/sbin/sshd -D&",
830 prompt="mininet>",
831 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700832 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800833 vars( self )[ key ] = connectargs[ key ]
834 response = self.execute(
835 cmd="xterm h1 h4 ",
836 prompt="mininet>",
837 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800838 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700841 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -0700842 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800843 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700844 if self.flag == 0:
845 self.flag = 1
846 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800847 else:
adminbae64d82013-08-01 10:50:15 -0700848 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800849
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700850 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700851 """
852 Moves a host from one switch to another on the fly
853 Note: The intf between host and oldSw when detached
854 using detach(), will still show up in the 'net'
855 cmd, because switch.detach() doesn't affect switch.intfs[]
856 ( which is correct behavior since the interfaces
857 haven't moved ).
858 """
859 if self.handle:
860 try:
861 # Bring link between oldSw-host down
862 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
863 "'," + "'down')"
864 print "cmd1= ", cmd
865 response = self.execute( cmd=cmd,
866 prompt="mininet>",
867 timeout=10 )
868
869 # Determine hostintf and Oldswitchintf
870 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
871 ")[0]"
872 print "cmd2= ", cmd
873 self.handle.sendline( cmd )
874 self.handle.expect( "mininet>" )
875
876 # Determine ip and mac address of the host-oldSw interface
877 cmd = "px ipaddr = hintf.IP()"
878 print "cmd3= ", cmd
879 self.handle.sendline( cmd )
880 self.handle.expect( "mininet>" )
881
882 cmd = "px macaddr = hintf.MAC()"
883 print "cmd3= ", cmd
884 self.handle.sendline( cmd )
885 self.handle.expect( "mininet>" )
886
887 # Detach interface between oldSw-host
888 cmd = "px " + oldSw + ".detach( sintf )"
889 print "cmd4= ", cmd
890 self.handle.sendline( cmd )
891 self.handle.expect( "mininet>" )
892
893 # Add link between host-newSw
894 cmd = "py net.addLink(" + host + "," + newSw + ")"
895 print "cmd5= ", cmd
896 self.handle.sendline( cmd )
897 self.handle.expect( "mininet>" )
898
899 # Determine hostintf and Newswitchintf
900 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
901 ")[0]"
902 print "cmd6= ", cmd
903 self.handle.sendline( cmd )
904 self.handle.expect( "mininet>" )
905
906 # Attach interface between newSw-host
907 cmd = "px " + newSw + ".attach( sintf )"
908 print "cmd3= ", cmd
909 self.handle.sendline( cmd )
910 self.handle.expect( "mininet>" )
911
912 # Set ipaddress of the host-newSw interface
913 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
914 print "cmd7 = ", cmd
915 self.handle.sendline( cmd )
916 self.handle.expect( "mininet>" )
917
918 # Set macaddress of the host-newSw interface
919 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
920 print "cmd8 = ", cmd
921 self.handle.sendline( cmd )
922 self.handle.expect( "mininet>" )
923
924 cmd = "net"
925 print "cmd9 = ", cmd
926 self.handle.sendline( cmd )
927 self.handle.expect( "mininet>" )
928 print "output = ", self.handle.before
929
930 # Determine ipaddress of the host-newSw interface
931 cmd = host + " ifconfig"
932 print "cmd10= ", cmd
933 self.handle.sendline( cmd )
934 self.handle.expect( "mininet>" )
935 print "ifconfig o/p = ", self.handle.before
936
937 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700938
939 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700940 main.log.error( self.name + ": TIMEOUT exception found" )
941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700942 main.cleanAndExit()
Jon Hall53c5e662016-04-13 16:06:56 -0700943 except pexpect.EOF:
944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
946 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700947 except Exception:
948 main.log.exception( self.name + ": Uncaught exception!" )
949 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700950
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700951 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800952 """
953 Moves a host from one switch to another on the fly
954 Note: The intf between host and oldSw when detached
955 using detach(), will still show up in the 'net'
956 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700957 ( which is correct behavior since the interfaces
958 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800959 """
960 if self.handle:
961 try:
Jon Hall439c8912016-04-15 02:22:03 -0700962 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800963 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700964 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800965 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800966 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800967 response = self.execute( cmd=cmd,
968 prompt="mininet>",
969 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700970
kelvin-onlaba1484582015-02-02 15:46:20 -0800971 # Determine hostintf and Oldswitchintf
972 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800973 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800974 print "cmd2= ", cmd
975 self.handle.sendline( cmd )
976 self.handle.expect( "mininet>" )
977
shahshreya73537862015-02-11 15:15:24 -0800978 # Determine ip and mac address of the host-oldSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700979 cmd = "px ipaddr = " + str( IP )
kelvin-onlaba1484582015-02-02 15:46:20 -0800980 print "cmd3= ", cmd
981 self.handle.sendline( cmd )
982 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800983
984 cmd = "px macaddr = hintf.MAC()"
985 print "cmd3= ", cmd
986 self.handle.sendline( cmd )
987 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700988
kelvin-onlaba1484582015-02-02 15:46:20 -0800989 # Detach interface between oldSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700990 cmd = "px " + oldSw + ".detach(sintf)"
kelvin-onlaba1484582015-02-02 15:46:20 -0800991 print "cmd4= ", cmd
992 self.handle.sendline( cmd )
993 self.handle.expect( "mininet>" )
994
995 # Add link between host-newSw
996 cmd = "py net.addLink(" + host + "," + newSw + ")"
997 print "cmd5= ", cmd
998 self.handle.sendline( cmd )
999 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001000
kelvin-onlaba1484582015-02-02 15:46:20 -08001001 # Determine hostintf and Newswitchintf
1002 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -08001003 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -08001004 print "cmd6= ", cmd
1005 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -07001006 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001007
1008 # Attach interface between newSw-host
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001009 cmd = "px " + newSw + ".attach(sintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001010 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001011 self.handle.sendline( cmd )
1012 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -08001013
1014 # Set macaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001015 cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -07001016 print "cmd7 = ", cmd
1017 self.handle.sendline( cmd )
1018 self.handle.expect( "mininet>" )
1019
1020 # Set ipaddress of the host-newSw interface
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001021 cmd = "px " + host + ".setIP(ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -08001022 print "cmd8 = ", cmd
1023 self.handle.sendline( cmd )
1024 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -07001025
Jon Hall439c8912016-04-15 02:22:03 -07001026 cmd = host + " ifconfig"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001027 print "cmd9 =", cmd
1028 response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
Jon Hall439c8912016-04-15 02:22:03 -07001029 print response
1030 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -07001031 ipAddressSearch = re.search( pattern, response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001032 print ipAddressSearch.group( 1 )
1033 intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
Jon Hall439c8912016-04-15 02:22:03 -07001034 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
1035 print "cmd10 = ", cmd
1036 self.handle.sendline( cmd )
1037 self.handle.expect( "mininet>" )
1038
kelvin-onlaba1484582015-02-02 15:46:20 -08001039 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -07001040 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001041 self.handle.sendline( cmd )
1042 self.handle.expect( "mininet>" )
1043 print "output = ", self.handle.before
1044
1045 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -08001046 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -07001047 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -08001048 self.handle.sendline( cmd )
1049 self.handle.expect( "mininet>" )
1050 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -07001051
kelvin-onlaba1484582015-02-02 15:46:20 -08001052 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001053 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001054 main.log.error( self.name + ": TIMEOUT exception found" )
1055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001056 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08001057 except pexpect.EOF:
1058 main.log.error( self.name + ": EOF exception found" )
1059 main.log.error( self.name + ": " + self.handle.before )
1060 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001061 except Exception:
1062 main.log.exception( self.name + ": Uncaught exception!" )
1063 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -08001064
Jon Hall7eb38402015-01-08 17:19:54 -08001065 def changeIP( self, host, intf, newIP, newNetmask ):
1066 """
1067 Changes the ip address of a host on the fly
1068 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001069 if self.handle:
1070 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001071 cmd = host + " ifconfig " + intf + " " + \
1072 newIP + " " + 'netmask' + " " + newNetmask
1073 self.handle.sendline( cmd )
1074 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001075 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001076 main.log.info( "response = " + response )
1077 main.log.info(
1078 "Ip of host " +
1079 host +
1080 " changed to new IP " +
1081 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001082 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001083 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001084 main.log.error( self.name + ": TIMEOUT exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001086 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001087 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001088 main.log.error( self.name + ": EOF exception found" )
1089 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001090 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001091 except Exception:
1092 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001093 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001094
Jon Hall7eb38402015-01-08 17:19:54 -08001095 def changeDefaultGateway( self, host, newGW ):
1096 """
1097 Changes the default gateway of a host
1098 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001099 if self.handle:
1100 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001101 cmd = host + " route add default gw " + newGW
1102 self.handle.sendline( cmd )
1103 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001104 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001105 main.log.info( "response = " + response )
1106 main.log.info(
1107 "Default gateway of host " +
1108 host +
1109 " changed to " +
1110 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001111 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001112 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001113 main.log.error( self.name + ": TIMEOUT exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001115 main.cleanAndExit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001116 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 main.log.error( self.name + ": EOF exception found" )
1118 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001119 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001120 except Exception:
1121 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001122 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001123
Jon Hall7eb38402015-01-08 17:19:54 -08001124 def addStaticMACAddress( self, host, GW, macaddr ):
1125 """
Jon Hallefbd9792015-03-05 16:11:36 -08001126 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001127 if self.handle:
1128 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001129 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1130 cmd = host + " arp -s " + GW + " " + macaddr
1131 self.handle.sendline( cmd )
1132 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001133 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001134 main.log.info( "response = " + response )
1135 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001136 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001137 GW +
1138 " changed to " +
1139 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001140 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001141 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001142 main.log.error( self.name + ": TIMEOUT exception found" )
1143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001144 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001145 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001148 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001149 except Exception:
1150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001151 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001152
Jon Hall7eb38402015-01-08 17:19:54 -08001153 def verifyStaticGWandMAC( self, host ):
1154 """
1155 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001156 if self.handle:
1157 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001158 # h1 arp -an
1159 cmd = host + " arp -an "
1160 self.handle.sendline( cmd )
1161 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001162 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001163 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001164 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001165 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001166 main.log.error( self.name + ": TIMEOUT exception found" )
1167 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001168 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001169 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001170 main.log.error( self.name + ": EOF exception found" )
1171 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001172 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001173 except Exception:
1174 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001175 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001176
Jon Hall7eb38402015-01-08 17:19:54 -08001177 def getMacAddress( self, host ):
1178 """
1179 Verifies the host's ip configured or not."""
1180 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001181 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001182 response = self.execute(
1183 cmd=host +
1184 " ifconfig",
1185 prompt="mininet>",
1186 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001187 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001188 main.log.error( self.name + ": EOF exception found" )
1189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001190 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001191 except Exception:
1192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001193 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001194
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001195 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 macAddressSearch = re.search( pattern, response, re.I )
1197 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001198 main.log.info(
1199 self.name +
1200 ": Mac-Address of Host " +
1201 host +
1202 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 macAddress )
1204 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001205 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001206 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001207
Jon Hall7eb38402015-01-08 17:19:54 -08001208 def getInterfaceMACAddress( self, host, interface ):
1209 """
1210 Return the IP address of the interface on the given host"""
1211 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001212 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001213 response = self.execute( cmd=host + " ifconfig " + interface,
1214 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001215 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 main.log.error( self.name + ": EOF exception found" )
1217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001218 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001219 except Exception:
1220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001221 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001222
1223 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 macAddressSearch = re.search( pattern, response, re.I )
1225 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001226 main.log.info( "No mac address found in %s" % response )
1227 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001229 main.log.info(
1230 "Mac-Address of " +
1231 host +
1232 ":" +
1233 interface +
1234 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 macAddress )
1236 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001237 else:
1238 main.log.error( "Connection failed to the host" )
1239
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001240 def getIPAddress( self, host , proto='IPV4' ):
Jon Hall7eb38402015-01-08 17:19:54 -08001241 """
1242 Verifies the host's ip configured or not."""
1243 if self.handle:
1244 try:
1245 response = self.execute(
1246 cmd=host +
1247 " ifconfig",
1248 prompt="mininet>",
1249 timeout=10 )
1250 except pexpect.EOF:
1251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001254 except Exception:
1255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001257
sathishmad953462015-12-03 17:42:07 +05301258 pattern = ''
1259 if proto == 'IPV4':
1260 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1261 else:
Jon Hall439c8912016-04-15 02:22:03 -07001262 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 ipAddressSearch = re.search( pattern, response )
Jon Hall3c910162018-03-07 14:42:16 -08001264 if not ipAddressSearch:
1265 return None
Jon Hall7eb38402015-01-08 17:19:54 -08001266 main.log.info(
1267 self.name +
1268 ": IP-Address of Host " +
1269 host +
1270 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 ipAddressSearch.group( 1 ) )
1272 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001273 else:
1274 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001275
Jon Hall7eb38402015-01-08 17:19:54 -08001276 def getSwitchDPID( self, switch ):
1277 """
1278 return the datapath ID of the switch"""
1279 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001280 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001281 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001282 response = self.execute(
1283 cmd=cmd,
1284 prompt="mininet>",
1285 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001286 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001289 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001292 main.cleanAndExit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001293 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001294 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001295 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001296 main.log.info(
1297 "Couldn't find DPID for switch %s, found: %s" %
1298 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001299 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001300 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001301 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001302 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001303
Jon Hall7eb38402015-01-08 17:19:54 -08001304 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001305 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001306 self.handle.sendline( "" )
1307 self.expect( "mininet>" )
1308 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001309 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001310 response = self.execute(
1311 cmd=cmd,
1312 prompt="mininet>",
1313 timeout=10 )
1314 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001315 response = self.handle.before
1316 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001317 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001318 main.log.error( self.name + ": TIMEOUT exception found" )
1319 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001320 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001321 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001324 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001325 except Exception:
1326 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001327 main.cleanAndExit()
admin2580a0e2014-07-29 11:24:34 -07001328
Jon Hall7eb38402015-01-08 17:19:54 -08001329 def getInterfaces( self, node ):
1330 """
1331 return information dict about interfaces connected to the node"""
1332 if self.handle:
1333 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001334 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001335 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001336 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001337 response = self.execute(
1338 cmd=cmd,
1339 prompt="mininet>",
1340 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001341 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001342 main.log.error( self.name + ": EOF exception found" )
1343 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001344 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001345 except Exception:
1346 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001347 main.cleanAndExit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001348 return response
1349 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001350 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001351
Jon Hall7eb38402015-01-08 17:19:54 -08001352 def dump( self ):
1353 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001354 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001355 response = self.execute(
1356 cmd='dump',
1357 prompt='mininet>',
1358 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001359 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001360 main.log.error( self.name + ": EOF exception found" )
1361 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001362 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001363 except Exception:
1364 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001365 main.cleanAndExit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001366 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001367
Jon Hall7eb38402015-01-08 17:19:54 -08001368 def intfs( self ):
1369 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001370 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 response = self.execute(
1372 cmd='intfs',
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 )
Devin Lim44075962017-08-11 10:56:37 -07001378 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001379 except Exception:
1380 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001381 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001382 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001383
Jon Hall7eb38402015-01-08 17:19:54 -08001384 def net( self ):
1385 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001386 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001387 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001388 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001389 main.log.error( self.name + ": EOF exception found" )
1390 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001391 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001392 except Exception:
1393 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001394 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001395 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001396
Devin Lima7cfdbd2017-09-29 15:02:22 -07001397 def links( self, timeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001398 main.log.info( self.name + ": List network links" )
1399 try:
1400 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001401 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001402 except pexpect.EOF:
1403 main.log.error( self.name + ": EOF exception found" )
1404 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001405 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001406 except Exception:
1407 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001408 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07001409 return response
1410
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001411 def iperftcpAll( self, hosts, timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001412 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001413 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001414
kelvin-onlab7cce9382015-07-17 10:21:03 -07001415 @parm:
1416 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1417 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001418 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001419 try:
1420 for host1 in hosts:
1421 for host2 in hosts:
1422 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001423 if self.iperftcp( host1, host2, timeout ) == main.FALSE:
1424 main.log.error( self.name + ": iperftcp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001425 except Exception:
1426 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001427 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001428
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001429 def iperftcp( self, host1="h1", host2="h2", timeout=6 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001430 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001431 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1432 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001433
kelvin-onlab7cce9382015-07-17 10:21:03 -07001434 @parm:
1435 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1436 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001437 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001438 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1439 try:
1440 # Setup the mininet command
1441 cmd1 = 'iperf ' + host1 + " " + host2
1442 self.handle.sendline( cmd1 )
1443 outcome = self.handle.expect( "mininet>", timeout )
1444 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001445
kelvin-onlab7cce9382015-07-17 10:21:03 -07001446 # checks if there are results in the mininet response
1447 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001448 main.log.report( self.name + ": iperf test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001449 # parse the mn results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001450 response = response.split( "\r\n" )
1451 response = response[ len( response )-2 ]
1452 response = response.split( ": " )
1453 response = response[ len( response )-1 ]
1454 response = response.replace( "[", "" )
1455 response = response.replace( "]", "" )
1456 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001457
kelvin-onlab7cce9382015-07-17 10:21:03 -07001458 # this is the bandwith two and from the two hosts
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001459 bandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001460
kelvin-onlab7cce9382015-07-17 10:21:03 -07001461 # there should be two elements in the bandwidth list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001462 # ['host1 to host2', 'host2 to host1"]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001463 if len( bandwidth ) == 2:
1464 main.log.report( self.name + ": iperf test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001465 return main.TRUE
1466 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001467 main.log.error( self.name + ": invalid iperf results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001468 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001469 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001470 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001471 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001472 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001473 main.log.error( self.name + ": TIMEOUT exception found" )
1474 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001475 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001476 # NOTE: Send ctrl-c to make sure iperf is done
Jon Hall2c5ac942018-03-23 11:26:54 -07001477 self.handle.send( "\x03" )
Jon Hall3b489db2015-10-05 14:38:37 -07001478 self.handle.expect( "Interrupt" )
1479 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001480 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001481 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001482 main.log.error( self.name + ": EOF exception found" )
1483 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001484 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001485 except Exception:
1486 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001487 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001488
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001489 def iperftcpipv6( self, host1="h1", host2="h2", timeout=50 ):
Jon Hall439c8912016-04-15 02:22:03 -07001490 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1491 try:
1492 IP1 = self.getIPAddress( host1, proto='IPV6' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001493 cmd1 = host1 + ' iperf -V -sD -B ' + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001494 self.handle.sendline( cmd1 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001495 outcome1 = self.handle.expect( "mininet>" )
1496 cmd2 = host2 + ' iperf -V -c ' + str( IP1 ) + ' -t 5'
Jon Hall439c8912016-04-15 02:22:03 -07001497 self.handle.sendline( cmd2 )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001498 outcome2 = self.handle.expect( "mininet>" )
Jon Hall439c8912016-04-15 02:22:03 -07001499 response1 = self.handle.before
1500 response2 = self.handle.after
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001501 print response1, response2
1502 pattern = "connected with " + str( IP1 )
Jon Hall439c8912016-04-15 02:22:03 -07001503 if pattern in response1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001504 main.log.report( self.name + ": iperf test completed" )
Jon Hall439c8912016-04-15 02:22:03 -07001505 return main.TRUE
1506 else:
1507 main.log.error( self.name + ": iperf test failed" )
1508 return main.FALSE
1509 except pexpect.TIMEOUT:
1510 main.log.error( self.name + ": TIMEOUT exception found" )
1511 main.log.error( self.name + " response: " + repr( self.handle.before ) )
Jon Hall2c5ac942018-03-23 11:26:54 -07001512 self.handle.send( "\x03" )
Jon Hall439c8912016-04-15 02:22:03 -07001513 self.handle.expect( "Interrupt" )
1514 self.handle.expect( "mininet>" )
1515 return main.FALSE
1516 except pexpect.EOF:
1517 main.log.error( self.name + ": EOF exception found" )
1518 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001519 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001520 except Exception:
1521 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001522 main.cleanAndExit()
Jon Hall439c8912016-04-15 02:22:03 -07001523
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001524 def iperfudpAll( self, hosts, bandwidth="10M" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001525 '''
GlennRC61321f22015-07-16 13:36:54 -07001526 Runs the iperfudp function with a given set of hosts and specified
1527 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001528
GlennRC61321f22015-07-16 13:36:54 -07001529 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001530 bandwidth: the targeted bandwidth, in megabits ('M')
1531 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001532 try:
1533 for host1 in hosts:
1534 for host2 in hosts:
1535 if host1 != host2:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001536 if self.iperfudp( host1, host2, bandwidth ) == main.FALSE:
1537 main.log.error( self.name + ": iperfudp test failed for " + host1 + " and " + host2 )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001538 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001539 main.log.exception( self.name + ": Object not as expected" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001540 return main.FALSE
1541 except Exception:
1542 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001543 main.cleanAndExit()
GlennRC61321f22015-07-16 13:36:54 -07001544
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001545 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001546 '''
kelvin-onlab7cce9382015-07-17 10:21:03 -07001547 Creates an iperf UDP test with a specific bandwidth.
1548 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001549
kelvin-onlab7cce9382015-07-17 10:21:03 -07001550 @param:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001551 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1552 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001553 main.log.info( self.name + ": Simple iperf UDP test between two hosts" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001554 try:
1555 # setup the mininet command
1556 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001557 self.handle.sendline( cmd )
1558 self.handle.expect( "mininet>" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001559 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001560
kelvin-onlab7cce9382015-07-17 10:21:03 -07001561 # check if there are in results in the mininet response
1562 if "Results:" in response:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001563 main.log.report( self.name + ": iperfudp test completed" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001564 # parse the results
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001565 response = response.split( "\r\n" )
1566 response = response[ len( response )-2 ]
1567 response = response.split( ": " )
1568 response = response[ len( response )-1 ]
1569 response = response.replace( "[", "" )
1570 response = response.replace( "]", "" )
1571 response = response.replace( "\'", "" )
GlennRC61321f22015-07-16 13:36:54 -07001572
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001573 mnBandwidth = response.split( ", " )
GlennRC61321f22015-07-16 13:36:54 -07001574
kelvin-onlab7cce9382015-07-17 10:21:03 -07001575 # check to see if there are at least three entries
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001576 # ['bandwidth', 'host1 to host2', 'host2 to host1']
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001577 if len( mnBandwidth ) == 3:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001578 # if one entry is blank then something is wrong
1579 for item in mnBandwidth:
1580 if item == "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001581 main.log.error( self.name + ": Could not parse iperf output" )
1582 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001583 return main.FALSE
1584 # otherwise results are vaild
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001585 main.log.report( self.name + ": iperfudp test successful" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001586 return main.TRUE
1587 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001588 main.log.error( self.name + ": invalid iperfudp results" )
kelvin-onlab7cce9382015-07-17 10:21:03 -07001589 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001590
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001591 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001592 main.log.error( self.name + ": TIMEOUT exception found" )
1593 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001594 main.cleanAndExit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001595 except pexpect.EOF:
1596 main.log.error( self.name + ": EOF exception found" )
1597 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001598 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001599 except Exception:
1600 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001601 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001602
Jon Hall7eb38402015-01-08 17:19:54 -08001603 def nodes( self ):
1604 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001605 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001606 response = self.execute(
1607 cmd='nodes',
1608 prompt='mininet>',
1609 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001610 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001611 main.log.error( self.name + ": EOF exception found" )
1612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001613 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001614 except Exception:
1615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001616 main.cleanAndExit()
Jon Hall668ed802014-04-08 17:17:59 -07001617 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001618
Jon Hall7eb38402015-01-08 17:19:54 -08001619 def pingpair( self ):
1620 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001621 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001622 response = self.execute(
1623 cmd='pingpair',
1624 prompt='mininet>',
1625 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001626 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001627 main.log.error( self.name + ": EOF exception found" )
1628 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001629 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001630 except Exception:
1631 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001632 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001633
Jon Hall7eb38402015-01-08 17:19:54 -08001634 if re.search( ',\s0\%\spacket\sloss', response ):
1635 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001636 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001637 else:
alisone4121a92016-11-22 16:31:36 -08001638 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001639 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001640
Jon Hall7eb38402015-01-08 17:19:54 -08001641 def link( self, **linkargs ):
1642 """
GlennRCed771242016-01-13 17:02:47 -08001643 Bring link( s ) between two nodes up or down
1644 """
Jon Hall6094a362014-04-11 14:46:56 -07001645 try:
GlennRCed771242016-01-13 17:02:47 -08001646 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1647 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1648 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1649 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1650
1651 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1652 cmd = "link {} {} {}".format( end1, end2, option )
1653 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001654 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001655 response = self.handle.before
1656 main.log.info( response )
Jon Hallab611372018-02-21 15:26:05 -08001657 if "not in network" in response:
1658 main.log.error( self.name + ": Could not find one of the endpoints of the link" )
1659 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08001660 return main.TRUE
1661 except pexpect.TIMEOUT:
1662 main.log.exception( self.name + ": Command timed out" )
1663 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001664 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001665 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07001666 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08001667 except Exception:
1668 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001669 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001670
pingping-lin8244a3b2015-09-16 13:36:56 -07001671 def switch( self, **switchargs ):
1672 """
1673 start/stop a switch
1674 """
1675 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1676 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1677 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1678 command = "switch " + str( sw ) + " " + str( option )
1679 main.log.info( command )
1680 try:
1681 self.handle.sendline( command )
1682 self.handle.expect( "mininet>" )
1683 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001684 main.log.error( self.name + ": TIMEOUT exception found" )
1685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001686 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001687 except pexpect.EOF:
1688 main.log.error( self.name + ": EOF exception found" )
1689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001690 main.cleanAndExit()
pingping-lin8244a3b2015-09-16 13:36:56 -07001691 return main.TRUE
1692
pingping-lin5bb663b2015-09-24 11:47:50 -07001693 def node( self, nodeName, commandStr ):
1694 """
1695 Carry out a command line on a given node
1696 @parm:
1697 nodeName: the node name in Mininet testbed
1698 commandStr: the command line will be carried out on the node
1699 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1700 """
1701 command = str( nodeName ) + " " + str( commandStr )
1702 main.log.info( command )
1703
1704 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001705 response = self.execute( cmd = command, prompt = "mininet>" )
pingping-lin5bb663b2015-09-24 11:47:50 -07001706 if re.search( "Unknown command", response ):
1707 main.log.warn( response )
1708 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001709 if re.search( "Permission denied", response ):
1710 main.log.warn( response )
1711 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001712 except pexpect.EOF:
1713 main.log.error( self.name + ": EOF exception found" )
1714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001715 main.cleanAndExit()
pingping-lin5bb663b2015-09-24 11:47:50 -07001716 main.log.info( " response is :" )
1717 main.log.info( response )
1718 return response
1719
Jon Hall7eb38402015-01-08 17:19:54 -08001720 def yank( self, **yankargs ):
1721 """
1722 yank a mininet switch interface to a host"""
1723 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001724 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001725 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1726 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001727 command = "py " + str( sw ) + '.detach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001728 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001729 response = self.execute(
1730 cmd=command,
1731 prompt="mininet>",
1732 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001733 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001734 main.log.error( self.name + ": EOF exception found" )
1735 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001736 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001737 except Exception:
1738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001739 main.cleanAndExit()
adminaeedddd2013-08-02 15:14:15 -07001740 return main.TRUE
1741
Jon Hall7eb38402015-01-08 17:19:54 -08001742 def plug( self, **plugargs ):
1743 """
1744 plug the yanked mininet switch interface to a switch"""
1745 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001746 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001747 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1748 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001749 command = "py " + str( sw ) + '.attach("' + str( intf ) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001750 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001751 response = self.execute(
1752 cmd=command,
1753 prompt="mininet>",
1754 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001755 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001758 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001759 except Exception:
1760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001761 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001762 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001763
Jon Hall7eb38402015-01-08 17:19:54 -08001764 def dpctl( self, **dpctlargs ):
1765 """
1766 Run dpctl command on all switches."""
1767 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001768 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001769 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1770 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1771 command = "dpctl " + cmd + " " + str( cmdargs )
1772 try:
1773 response = self.execute(
1774 cmd=command,
1775 prompt="mininet>",
1776 timeout=10 )
1777 except pexpect.EOF:
1778 main.log.error( self.name + ": EOF exception found" )
1779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001780 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001781 except Exception:
1782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001783 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08001784 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001785
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001787 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001788 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001789 try:
1790 fileInput = path + '/lib/Mininet/INSTALL'
1791 version = super( Mininet, self ).getVersion()
1792 pattern = 'Mininet\s\w\.\w\.\w\w*'
1793 for line in open( fileInput, 'r' ).readlines():
1794 result = re.match( pattern, line )
1795 if result:
1796 version = result.group( 0 )
1797 return version
1798 except Exception:
1799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001800 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001801
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001803 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001804 Parameters:
1805 sw: The name of an OVS switch. Example "s1"
1806 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001807 The output of the command from the mininet cli
1808 or main.FALSE on timeout"""
1809 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001810 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001811 response = self.execute(
1812 cmd=command,
1813 prompt="mininet>",
1814 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001815 if response:
Jon Hallab611372018-02-21 15:26:05 -08001816 if "no bridge named" in response:
1817 main.log.error( self.name + ": Error in getSwController: " +
1818 self.handle.before )
1819 return main.FALSE
1820 else:
1821 return response
admin2a9548d2014-06-17 14:08:07 -07001822 else:
1823 return main.FALSE
1824 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001825 main.log.error( self.name + ": EOF exception found" )
1826 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001827 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001828 except Exception:
1829 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001830 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001831
Charles Chan029be652015-08-24 01:46:10 +08001832 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001833 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001834 Description:
1835 Assign switches to the controllers ( for ovs use only )
1836 Required:
1837 sw - Name of the switch. This can be a list or a string.
1838 ip - Ip addresses of controllers. This can be a list or a string.
1839 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001840 port - ONOS use port 6653, if no list of ports is passed, then
1841 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001842 ptcp - ptcp number, This can be a string or a list that has
1843 the same length as switch. This is optional and not required
1844 when using ovs switches.
1845 NOTE: If switches and ptcp are given in a list type they should have the
1846 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1847 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001848
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001849 Return:
1850 Returns main.TRUE if mininet correctly assigned switches to
1851 controllers, otherwise it will return main.FALSE or an appropriate
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001852 exception(s)
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001853 """
1854 assignResult = main.TRUE
1855 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001856 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001857 command = "sh ovs-vsctl set-controller "
1858 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001859 try:
1860 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001861 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001862 if isinstance( port, types.StringType ) or \
1863 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001864 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001865 elif isinstance( port, types.ListType ):
1866 main.log.error( self.name + ": Only one controller " +
1867 "assigned and a list of ports has" +
1868 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001869 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001870 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001871 main.log.error( self.name + ": Invalid controller port " +
1872 "number. Please specify correct " +
1873 "controller port" )
1874 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001875
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001876 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001877 if isinstance( port, types.StringType ) or \
1878 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001879 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001880 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1881 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001882 elif isinstance( port, types.ListType ):
1883 if ( len( ip ) != len( port ) ):
1884 main.log.error( self.name + ": Port list = " +
1885 str( len( port ) ) +
1886 "should be the same as controller" +
1887 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001888 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001889 else:
1890 onosIp = ""
1891 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001892 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1893 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001894 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001895 main.log.error( self.name + ": Invalid controller port " +
1896 "number. Please specify correct " +
1897 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001898 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001899 else:
1900 main.log.error( self.name + ": Invalid ip address" )
1901 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001902
1903 if isinstance( sw, types.StringType ):
1904 command += sw + " "
1905 if ptcp:
1906 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001907 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001908 elif isinstance( ptcp, types.ListType ):
1909 main.log.error( self.name + ": Only one switch is " +
1910 "being set and multiple PTCP is " +
1911 "being passed " )
1912 else:
1913 main.log.error( self.name + ": Invalid PTCP" )
1914 ptcp = ""
1915 command += onosIp
1916 commandList.append( command )
1917
1918 elif isinstance( sw, types.ListType ):
1919 if ptcp:
1920 if isinstance( ptcp, types.ListType ):
1921 if len( ptcp ) != len( sw ):
1922 main.log.error( self.name + ": PTCP length = " +
1923 str( len( ptcp ) ) +
1924 " is not the same as switch" +
1925 " length = " +
1926 str( len( sw ) ) )
1927 return main.FALSE
1928 else:
1929 for switch, ptcpNum in zip( sw, ptcp ):
1930 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001931 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001932 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001933 tempCmd += onosIp
1934 commandList.append( tempCmd )
1935 else:
1936 main.log.error( self.name + ": Invalid PTCP" )
1937 return main.FALSE
1938 else:
1939 for switch in sw:
1940 tempCmd = "sh ovs-vsctl set-controller "
1941 tempCmd += switch + " " + onosIp
1942 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001943 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001944 main.log.error( self.name + ": Invalid switch type " )
1945 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001946
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001947 for cmd in commandList:
1948 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001949 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
Jon Hallab611372018-02-21 15:26:05 -08001950 if "no bridge named" in self.handle.before:
1951 main.log.error( self.name + ": Error in assignSwController: " +
1952 self.handle.before )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001953 except pexpect.TIMEOUT:
1954 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1955 return main.FALSE
1956 except pexpect.EOF:
1957 main.log.error( self.name + ": EOF exception found" )
1958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001959 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001960 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001961 except pexpect.EOF:
1962 main.log.error( self.name + ": EOF exception found" )
1963 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001964 main.cleanAndExit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001965 except Exception:
1966 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001967 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07001968
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001970 """
1971 Removes the controller target from sw"""
1972 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001973 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001974 response = self.execute(
1975 cmd=command,
1976 prompt="mininet>",
1977 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001978 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001979 main.log.error( self.name + ": EOF exception found" )
1980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001981 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001982 except Exception:
1983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001984 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07001985 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001986 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001987
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001989 """
Jon Hallb1290e82014-11-18 16:17:48 -05001990 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001991 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001992 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001993 NOTE: cannot currently specify what type of switch
1994 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001995 sw = name of the new switch as a string
1996 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001997 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001998 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001999 """
2000 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002001 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05002002 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002003 response = self.execute(
2004 cmd=command,
2005 prompt="mininet>",
2006 timeout=10 )
2007 if re.search( "already exists!", response ):
2008 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002009 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002010 elif re.search( "Error", response ):
2011 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002012 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002013 elif re.search( "usage:", response ):
2014 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002015 return main.FALSE
2016 else:
2017 return main.TRUE
2018 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002019 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07002020 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002021 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002022 except Exception:
2023 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002024 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002025
kelvin-onlabd3b64892015-01-20 13:26:24 -08002026 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002027 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002028 delete a switch from the mininet topology
2029 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002030 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002031 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002032 sw = name of the switch as a string
2033 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002034 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002035 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002036 response = self.execute(
2037 cmd=command,
2038 prompt="mininet>",
2039 timeout=10 )
2040 if re.search( "no switch named", response ):
2041 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002042 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002043 elif re.search( "Error", response ):
2044 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002045 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002046 elif re.search( "usage:", response ):
2047 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002048 return main.FALSE
2049 else:
2050 return main.TRUE
2051 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002052 main.log.error( self.name + ": EOF exception found" )
2053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002055 except Exception:
2056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002058
You Wangdb8cd0a2016-05-26 15:19:45 -07002059 def getSwitchRandom( self, timeout=60, nonCut=True ):
2060 """
2061 Randomly get a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002062 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002063 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002064 components of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002065 it just randomly returns one switch from all current switches in
2066 Mininet.
2067 Returns the name of the chosen switch.
2068 """
2069 import random
2070 candidateSwitches = []
2071 try:
2072 if not nonCut:
2073 switches = self.getSwitches( timeout=timeout )
2074 assert len( switches ) != 0
2075 for switchName in switches.keys():
2076 candidateSwitches.append( switchName )
2077 else:
2078 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002079 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002080 return None
2081 self.graph.update( graphDict )
2082 candidateSwitches = self.graph.getNonCutVertices()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002083 if candidateSwitches is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002084 return None
2085 elif len( candidateSwitches ) == 0:
2086 main.log.info( self.name + ": No candidate switch for deletion" )
2087 return None
2088 else:
2089 switch = random.sample( candidateSwitches, 1 )
2090 return switch[ 0 ]
2091 except KeyError:
2092 main.log.exception( self.name + ": KeyError exception found" )
2093 return None
2094 except AssertionError:
2095 main.log.exception( self.name + ": AssertionError exception found" )
2096 return None
2097 except Exception:
2098 main.log.exception( self.name + ": Uncaught exception" )
2099 return None
2100
2101 def delSwitchRandom( self, timeout=60, nonCut=True ):
2102 """
2103 Randomly delete a switch from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002104 If nonCut is True, it gets a list of non-cut switches (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002105 of a non-cut switch will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002106 components of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002107 otherwise it just randomly delete one switch from all current
2108 switches in Mininet.
2109 Returns the name of the deleted switch
2110 """
2111 try:
2112 switch = self.getSwitchRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002113 if switch is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002114 return None
2115 else:
2116 deletionResult = self.delSwitch( switch )
2117 if deletionResult:
2118 return switch
2119 else:
2120 return None
2121 except Exception:
2122 main.log.exception( self.name + ": Uncaught exception" )
2123 return None
2124
kelvin-onlabd3b64892015-01-20 13:26:24 -08002125 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002126 """
2127 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002128 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002129 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002130 NOTE: cannot currently specify what type of link
2131 required params:
2132 node1 = the string node name of the first endpoint of the link
2133 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002134 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002135 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002136 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002137 response = self.execute(
2138 cmd=command,
2139 prompt="mininet>",
2140 timeout=10 )
2141 if re.search( "doesnt exist!", response ):
2142 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002143 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002144 elif re.search( "Error", response ):
2145 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002146 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002147 elif re.search( "usage:", response ):
2148 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002149 return main.FALSE
2150 else:
2151 return main.TRUE
2152 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002153 main.log.error( self.name + ": EOF exception found" )
2154 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002155 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002156 except Exception:
2157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002158 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002159
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002161 """
2162 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002163 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002164 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002165 required params:
2166 node1 = the string node name of the first endpoint of the link
2167 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002168 returns: main.FALSE on an error, else main.TRUE
2169 """
Jon Hallffb386d2014-11-21 13:43:38 -08002170 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002171 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002172 response = self.execute(
2173 cmd=command,
2174 prompt="mininet>",
2175 timeout=10 )
2176 if re.search( "no node named", response ):
2177 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002178 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002179 elif re.search( "Error", response ):
2180 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002181 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002182 elif re.search( "usage:", response ):
2183 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002184 return main.FALSE
2185 else:
2186 return main.TRUE
2187 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002190 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002193 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002194
You Wangdb8cd0a2016-05-26 15:19:45 -07002195 def getLinkRandom( self, timeout=60, nonCut=True ):
2196 """
2197 Randomly get a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002198 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002199 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002200 component of a graph) and randomly returns one of them, otherwise
You Wangdb8cd0a2016-05-26 15:19:45 -07002201 it just randomly returns one link from all current links in
2202 Mininet.
2203 Returns the link as a list, e.g. [ 's1', 's2' ]
2204 """
2205 import random
2206 candidateLinks = []
2207 try:
2208 if not nonCut:
2209 links = self.getLinks( timeout=timeout )
2210 assert len( links ) != 0
2211 for link in links:
2212 # Exclude host-switch link
2213 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2214 continue
2215 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2216 else:
2217 graphDict = self.getGraphDict( timeout=timeout, useId=False )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002218 if graphDict is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002219 return None
2220 self.graph.update( graphDict )
2221 candidateLinks = self.graph.getNonCutEdges()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002222 if candidateLinks is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002223 return None
2224 elif len( candidateLinks ) == 0:
2225 main.log.info( self.name + ": No candidate link for deletion" )
2226 return None
2227 else:
2228 link = random.sample( candidateLinks, 1 )
2229 return link[ 0 ]
2230 except KeyError:
2231 main.log.exception( self.name + ": KeyError exception found" )
2232 return None
2233 except AssertionError:
2234 main.log.exception( self.name + ": AssertionError exception found" )
2235 return None
2236 except Exception:
2237 main.log.exception( self.name + ": Uncaught exception" )
2238 return None
2239
2240 def delLinkRandom( self, timeout=60, nonCut=True ):
2241 """
2242 Randomly delete a link from Mininet topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002243 If nonCut is True, it gets a list of non-cut links (the deletion
You Wangdb8cd0a2016-05-26 15:19:45 -07002244 of a non-cut link will not increase the number of connected
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002245 component of a graph) and randomly chooses one for deletion,
You Wangdb8cd0a2016-05-26 15:19:45 -07002246 otherwise it just randomly delete one link from all current links
2247 in Mininet.
2248 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2249 """
2250 try:
2251 link = self.getLinkRandom( timeout, nonCut )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002252 if link is None:
You Wangdb8cd0a2016-05-26 15:19:45 -07002253 return None
2254 else:
2255 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2256 if deletionResult:
2257 return link
2258 else:
2259 return None
2260 except Exception:
2261 main.log.exception( self.name + ": Uncaught exception" )
2262 return None
2263
kelvin-onlabd3b64892015-01-20 13:26:24 -08002264 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002265 """
Jon Hallb1290e82014-11-18 16:17:48 -05002266 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002267 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002268 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002269 NOTE: cannot currently specify what type of host
2270 required params:
2271 hostname = the string hostname
2272 optional key-value params
2273 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002274 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002275 """
2276 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002277 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002278 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002279 response = self.execute(
2280 cmd=command,
2281 prompt="mininet>",
2282 timeout=10 )
2283 if re.search( "already exists!", response ):
2284 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002285 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002286 elif re.search( "doesnt exists!", response ):
2287 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002288 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002289 elif re.search( "Error", response ):
2290 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002291 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002292 elif re.search( "usage:", response ):
2293 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002294 return main.FALSE
2295 else:
2296 return main.TRUE
2297 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002298 main.log.error( self.name + ": EOF exception found" )
2299 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002300 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002301 except Exception:
2302 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002303 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05002304
kelvin-onlabd3b64892015-01-20 13:26:24 -08002305 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002306 """
2307 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002308 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002309 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002310 NOTE: this uses a custom mn function
2311 required params:
2312 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002313 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002314 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002315 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002316 response = self.execute(
2317 cmd=command,
2318 prompt="mininet>",
2319 timeout=10 )
2320 if re.search( "no host named", response ):
2321 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002322 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002323 elif re.search( "Error", response ):
2324 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002325 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002326 elif re.search( "usage:", response ):
2327 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002328 return main.FALSE
2329 else:
2330 return main.TRUE
2331 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002332 main.log.error( self.name + ": EOF exception found" )
2333 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002334 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002335 except Exception:
2336 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002337 main.cleanAndExit()
Jon Hall0819fd92014-05-23 12:08:13 -07002338
Jon Hall7eb38402015-01-08 17:19:54 -08002339 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002340 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002341 Called at the end of the test to stop the mininet and
2342 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002343 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002344 try:
2345 self.handle.sendline( '' )
2346 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2347 timeout=2 )
2348 response = main.TRUE
2349 if i == 0:
2350 response = self.stopNet()
2351 elif i == 1:
2352 return main.TRUE
2353 # print "Disconnecting Mininet"
2354 if self.handle:
2355 self.handle.sendline( "exit" )
2356 self.handle.expect( "exit" )
2357 self.handle.expect( "(.*)" )
2358 else:
2359 main.log.error( "Connection failed to the host" )
2360 return response
2361 except pexpect.EOF:
2362 main.log.error( self.name + ": EOF exception found" )
2363 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002364 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002365 except Exception:
2366 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002367 main.cleanAndExit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002368
Devin Lima7cfdbd2017-09-29 15:02:22 -07002369 def stopNet( self, fileName="", timeout=5, exitTimeout=1000 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002370 """
Jon Hall21270ac2015-02-16 17:59:55 -08002371 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002372 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002373 main.FALSE if the pexpect handle does not exist.
2374
Jon Halld61331b2015-02-17 16:35:47 -08002375 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002376 """
Jon Halld61331b2015-02-17 16:35:47 -08002377 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002378 response = ''
2379 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002380 try:
Jon Halld80cc142015-07-06 13:36:05 -07002381 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002382 i = self.handle.expect( [ 'mininet>',
Devin Limdc78e202017-06-09 18:30:07 -07002383 self.prompt,
kelvin-onlab56a3f462015-02-06 14:04:43 -08002384 pexpect.EOF,
2385 pexpect.TIMEOUT ],
2386 timeout )
2387 if i == 0:
Devin Lima7cfdbd2017-09-29 15:02:22 -07002388 main.log.info( "Exiting mininet.." )
2389 startTime = time.time()
Jeremyd9e4eb12016-04-13 12:09:06 -07002390 response = self.execute( cmd="exit",
Devin Lima7cfdbd2017-09-29 15:02:22 -07002391 prompt=self.prompt,
2392 timeout=exitTimeout )
2393 main.log.info( self.name + ": Stopped\nTime Took : " + str( time.time() - startTime ) )
Jeremyd9e4eb12016-04-13 12:09:06 -07002394 self.handle.sendline( "sudo mn -c" )
2395 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002396
Jeremyd9e4eb12016-04-13 12:09:06 -07002397 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002398 main.log.info( " Mininet trying to exit while not " +
2399 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002400 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002401 elif i == 2:
2402 main.log.error( "Something went wrong exiting mininet" )
2403 elif i == 3: # timeout
2404 main.log.error( "Something went wrong exiting mininet " +
2405 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002406
Hari Krishnab35c6d02015-03-18 11:13:51 -07002407 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002408 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -07002409 self.handle.expect( self.prompt )
Jon Halld80cc142015-07-06 13:36:05 -07002410 self.handle.sendline(
2411 "sudo kill -9 \`ps -ef | grep \"" +
2412 fileName +
2413 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002414 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002415 main.log.error( self.name + ": TIMEOUT exception found" )
2416 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002417 main.cleanAndExit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002418 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002419 main.log.error( self.name + ": EOF exception found" )
2420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002421 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002422 except Exception:
2423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002424 main.cleanAndExit()
Jon Hall7eb38402015-01-08 17:19:54 -08002425 else:
2426 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002427 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002428 return response
2429
YPZhang26a139e2016-04-25 14:01:55 -07002430 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002431 """
2432 Description:
2433 Sends arp message from mininet host for hosts discovery
2434 Required:
2435 host - hosts name
2436 Optional:
2437 ip - ip address that does not exist in the network so there would
2438 be no reply.
2439 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002440 if ethDevice:
2441 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002442 cmd = srcHost + " arping -c1 "
2443 if noResult:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002444 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
YPZhang26a139e2016-04-25 14:01:55 -07002445 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002446 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002447 if output:
2448 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002449 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002450 i = self.handle.expect( [ "mininet>", "arping: " ] )
2451 if i == 0:
2452 return main.TRUE
2453 elif i == 1:
2454 response = self.handle.before + self.handle.after
2455 self.handle.expect( "mininet>" )
2456 response += self.handle.before + self.handle.after
2457 main.log.warn( "Error sending arping, output was: " +
2458 response )
2459 return main.FALSE
2460 except pexpect.TIMEOUT:
2461 main.log.error( self.name + ": TIMEOUT exception found" )
2462 main.log.warn( self.handle.before )
2463 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002464 except pexpect.EOF:
2465 main.log.error( self.name + ": EOF exception found" )
2466 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002467 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002468 except Exception:
2469 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002470 main.cleanAndExit()
admin07529932013-11-22 14:58:28 -08002471
Jon Hall7eb38402015-01-08 17:19:54 -08002472 def decToHex( self, num ):
2473 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002474
Jon Hall7eb38402015-01-08 17:19:54 -08002475 def getSwitchFlowCount( self, switch ):
2476 """
2477 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002478 if self.handle:
2479 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2480 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002481 response = self.execute(
2482 cmd=cmd,
2483 prompt="mininet>",
2484 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002485 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002486 main.log.error( self.name + ": EOF exception found" )
2487 main.log.error( self.name + " " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002488 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002489 except Exception:
2490 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002491 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002492 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002493 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002494 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002495 main.log.info(
2496 "Couldn't find flows on switch %s, found: %s" %
2497 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002498 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002499 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002500 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002501 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002502
Jon Hall9ed8f372016-02-24 17:34:07 -08002503 def checkFlows( self, sw, dumpFormat=None ):
2504 if dumpFormat:
2505 command = "sh ovs-ofctl -F " + \
2506 dumpFormat + " dump-flows " + str( sw )
2507 else:
2508 command = "sh ovs-ofctl dump-flows " + str( sw )
2509 try:
2510 response = self.execute(
2511 cmd=command,
2512 prompt="mininet>",
2513 timeout=10 )
2514 return response
2515 except pexpect.EOF:
2516 main.log.error( self.name + ": EOF exception found" )
2517 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002518 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002519 except Exception:
2520 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002521 main.cleanAndExit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002522
GlennRC68467eb2015-11-16 18:01:01 -08002523 def flowTableComp( self, flowTable1, flowTable2 ):
2524 # This function compares the selctors and treatments of each flow
2525 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002526 assert flowTable1, "flowTable1 is empty or None"
2527 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002528 returnValue = main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002529 if len( flowTable1 ) != len( flowTable2 ):
GlennRC68467eb2015-11-16 18:01:01 -08002530 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002531 returnValue = main.FALSE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002532 dFields = [ "n_bytes", "cookie", "n_packets", "duration" ]
2533 for flow1, flow2 in zip( flowTable1, flowTable2 ):
Jon Hallacd1b182015-12-17 11:43:20 -08002534 for field in dFields:
2535 try:
2536 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002537 except KeyError:
2538 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002539 try:
2540 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002541 except KeyError:
2542 pass
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002543 for i in range( len( flowTable1 ) ):
2544 if flowTable1[ i ] not in flowTable2:
GlennRC17bbcf52015-12-14 17:31:50 -08002545 main.log.warn( "Flow tables do not match:" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002546 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[ i ] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002547 returnValue = main.FALSE
2548 break
2549 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002550 except AssertionError:
2551 main.log.exception( "Nothing to compare" )
2552 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002553 except Exception:
2554 main.log.exception( "Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002555 main.cleanAndExit()
Jon Hall9043c902015-07-30 14:23:44 -07002556
GlennRC528ad292015-11-12 10:38:18 -08002557 def parseFlowTable( self, flowTable, version="", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002558 '''
GlennRC956ea742015-11-05 16:14:15 -08002559 Discription: Parses flows into json format.
2560 NOTE: this can parse any string thats separated with commas
2561 Arguments:
2562 Required:
2563 flows: a list of strings that represnt flows
2564 Optional:
2565 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2566 debug: prints out the final result
2567 returns: A list of flows in json format
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002568 '''
GlennRC528ad292015-11-12 10:38:18 -08002569 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002570 try:
2571 for flow in flowTable:
2572 jsonFlow = {}
2573 # split up the fields of the flow
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002574 parsedFlow = flow.split( ", " )
You Wang91c37cf2016-05-23 09:39:42 -07002575 # get rid of any spaces in front of the field
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002576 for i in range( len( parsedFlow ) ):
2577 item = parsedFlow[ i ]
2578 if item[ 0 ] == " ":
2579 parsedFlow[ i ] = item[ 1: ]
You Wang91c37cf2016-05-23 09:39:42 -07002580 # grab the selector and treatment from the parsed flow
2581 # the last element is the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002582 temp = parsedFlow.pop( -1 )
You Wang91c37cf2016-05-23 09:39:42 -07002583 # split up the selector and the treatment
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002584 temp = temp.split( " " )
You Wang91c37cf2016-05-23 09:39:42 -07002585 index = 0
2586 # parse the flags
2587 # NOTE: This only parses one flag
2588 flag = {}
2589 if version == "1.3":
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002590 flag = { "flag": [ temp[ index ] ] }
You Wang91c37cf2016-05-23 09:39:42 -07002591 index += 1
2592 # the first element is the selector and split it up
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002593 sel = temp[ index ]
GlennRC528ad292015-11-12 10:38:18 -08002594 index += 1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002595 sel = sel.split( "," )
You Wang91c37cf2016-05-23 09:39:42 -07002596 # the priority is stuck in the selecter so put it back
2597 # in the flow
Jon Hallab611372018-02-21 15:26:05 -08002598 if 'priority' in sel[0]:
2599 parsedFlow.append( sel.pop( 0 ) )
You Wang91c37cf2016-05-23 09:39:42 -07002600 # parse selector
2601 criteria = []
2602 for item in sel:
2603 # this is the type of the packet e.g. "arp"
2604 if "=" not in item:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002605 criteria.append( { "type": item } )
You Wang91c37cf2016-05-23 09:39:42 -07002606 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002607 field = item.split( "=" )
2608 criteria.append( { field[ 0 ]: field[ 1 ] } )
2609 selector = { "selector": { "criteria": sorted( criteria ) } }
2610 treat = temp[ index ]
You Wang91c37cf2016-05-23 09:39:42 -07002611 # get rid of the action part e.g. "action=output:2"
2612 # we will add it back later
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002613 treat = treat.split( "=" )
2614 treat.pop( 0 )
You Wang91c37cf2016-05-23 09:39:42 -07002615 # parse treatment
2616 action = []
2617 for item in treat:
Jon Hallab611372018-02-21 15:26:05 -08002618 if ":" in item:
2619 field = item.split( ":" )
2620 action.append( { field[ 0 ]: field[ 1 ] } )
2621 else:
2622 main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
2623 item ) )
You Wang91c37cf2016-05-23 09:39:42 -07002624 # create the treatment field and add the actions
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002625 treatment = { "treatment": { "action": sorted( action ) } }
You Wang91c37cf2016-05-23 09:39:42 -07002626 # parse the rest of the flow
2627 for item in parsedFlow:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002628 field = item.split( "=" )
2629 jsonFlow.update( { field[ 0 ]: field[ 1 ] } )
You Wang91c37cf2016-05-23 09:39:42 -07002630 # add the treatment and the selector to the json flow
2631 jsonFlow.update( selector )
2632 jsonFlow.update( treatment )
2633 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002634
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002635 if debug:
2636 main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format( jsonFlow ) )
GlennRC956ea742015-11-05 16:14:15 -08002637
You Wang91c37cf2016-05-23 09:39:42 -07002638 # add the json flow to the json flow table
2639 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002640
You Wang91c37cf2016-05-23 09:39:42 -07002641 return jsonFlowTable
2642
2643 except IndexError:
2644 main.log.exception( self.name + ": IndexError found" )
2645 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002646 except pexpect.EOF:
2647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
You Wang91c37cf2016-05-23 09:39:42 -07002650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002652 main.cleanAndExit()
GlennRC528ad292015-11-12 10:38:18 -08002653
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002654 def getFlowTable( self, sw, version="", debug=False ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002655 '''
2656 Discription: Returns the flow table(s) on a switch or switches in a list.
GlennRC956ea742015-11-05 16:14:15 -08002657 Each element is a flow.
2658 Arguments:
2659 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002660 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002661 a list of switches.
2662 Optional:
2663 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2664 debug: prints out the final result
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002665 '''
GlennRC956ea742015-11-05 16:14:15 -08002666 try:
2667 switches = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002668 if isinstance( sw, list ):
2669 switches.extend( sw )
2670 else:
2671 switches.append( sw )
GlennRC956ea742015-11-05 16:14:15 -08002672
2673 flows = []
2674 for s in switches:
2675 cmd = "sh ovs-ofctl dump-flows " + s
2676
GlennRC528ad292015-11-12 10:38:18 -08002677 if "1.0" == version:
2678 cmd += " -F OpenFlow10-table_id"
2679 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002680 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002681
2682 main.log.info( "Sending: " + cmd )
2683 self.handle.sendline( cmd )
2684 self.handle.expect( "mininet>" )
2685 response = self.handle.before
2686 response = response.split( "\r\n" )
2687 # dump the first two elements and the last
2688 # the first element is the command that was sent
2689 # the second is the table header
2690 # the last element is empty
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002691 response = response[ 2:-1 ]
GlennRC956ea742015-11-05 16:14:15 -08002692 flows.extend( response )
2693
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002694 if debug:
2695 print "Flows:\n{}\n\n".format( flows )
GlennRC956ea742015-11-05 16:14:15 -08002696
GlennRC528ad292015-11-12 10:38:18 -08002697 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002698
GlennRC956ea742015-11-05 16:14:15 -08002699 except pexpect.EOF:
2700 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07002701 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002702 except Exception:
2703 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002704 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002705
2706 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002707 '''
GlennRC956ea742015-11-05 16:14:15 -08002708 Discription: Checks whether the ID provided matches a flow ID in Mininet
2709 Arguments:
2710 Required:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002711 sw: The switch name ("s1") to retrive the flow table. Can also be
GlennRC956ea742015-11-05 16:14:15 -08002712 a list of switches.
2713 flowId: the flow ID in hex format. Can also be a list of IDs
2714 Optional:
2715 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2716 debug: prints out the final result
2717 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2718 NOTE: prints out IDs that are not present
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002719 '''
GlennRC956ea742015-11-05 16:14:15 -08002720 try:
2721 main.log.info( "Getting flows from Mininet" )
2722 flows = self.getFlowTable( sw, version, debug )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002723 if flows is None:
You Wang083ae982016-05-25 09:31:09 -07002724 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002725
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002726 if debug:
2727 print "flow ids:\n{}\n\n".format( flowId )
GlennRC956ea742015-11-05 16:14:15 -08002728
2729 # Check flowId is a list or a string
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 if isinstance( flowId, str ):
GlennRC956ea742015-11-05 16:14:15 -08002731 result = False
2732 for f in flows:
2733 if flowId in f.get( 'cookie' ):
2734 result = True
2735 break
2736 # flowId is a list
2737 else:
2738 result = True
2739 # Get flow IDs from Mininet
2740 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2741 # Save the IDs that are not in Mininet
2742 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2743
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002744 if debug:
2745 print "mn flow ids:\n{}\n\n".format( mnFlowIds )
GlennRC956ea742015-11-05 16:14:15 -08002746
2747 # Print out the IDs that are not in Mininet
2748 if absentIds:
2749 main.log.warn( "Absent ids: {}".format( absentIds ) )
2750 result = False
2751
2752 return main.TRUE if result else main.FALSE
2753
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002754 except pexpect.EOF:
2755 main.log.error( self.name + ": EOF exception found" )
2756 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002757 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002758 except Exception:
2759 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002760 main.cleanAndExit()
GlennRC956ea742015-11-05 16:14:15 -08002761
Charles Chan029be652015-08-24 01:46:10 +08002762 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002763 """
Jon Hallefbd9792015-03-05 16:11:36 -08002764 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002765 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002766 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002767 self.handle.sendline( "" )
2768 self.handle.expect( "mininet>" )
2769 self.handle.sendline(
2770 "sh sudo tcpdump -n -i " +
2771 intf +
2772 " " +
2773 port +
2774 " -w " +
2775 filename.strip() +
2776 " &" )
2777 self.handle.sendline( "" )
2778 i = self.handle.expect( [ 'No\ssuch\device',
2779 'listening\son',
2780 pexpect.TIMEOUT,
2781 "mininet>" ],
2782 timeout=10 )
2783 main.log.warn( self.handle.before + self.handle.after )
2784 self.handle.sendline( "" )
2785 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002786 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002787 main.log.error(
2788 self.name +
2789 ": tcpdump - No such device exists. " +
2790 "tcpdump attempted on: " +
2791 intf )
admin2a9548d2014-06-17 14:08:07 -07002792 return main.FALSE
2793 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002794 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002795 return main.TRUE
2796 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002797 main.log.error(
2798 self.name +
2799 ": tcpdump command timed out! Check interface name," +
2800 " given interface was: " +
2801 intf )
admin2a9548d2014-06-17 14:08:07 -07002802 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002803 elif i == 3:
2804 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002805 return main.TRUE
2806 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002807 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002808 return main.FALSE
2809 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002810 main.log.error( self.name + ": EOF exception found" )
2811 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002812 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002813 except Exception:
2814 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002815 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002816
kelvin-onlabd3b64892015-01-20 13:26:24 -08002817 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002818 """
2819 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002820 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002821 self.handle.sendline( "sh sudo pkill tcpdump" )
2822 self.handle.expect( "mininet>" )
2823 self.handle.sendline( "" )
2824 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002825 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002826 main.log.error( self.name + ": TIMEOUT exception found" )
2827 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002828 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002829 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002830 main.log.error( self.name + ": EOF exception found" )
2831 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002832 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002833 except Exception:
2834 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002835 main.cleanAndExit()
admin2a9548d2014-06-17 14:08:07 -07002836
Jon Halld80cc142015-07-06 13:36:05 -07002837 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002838 """
2839 Read ports from a Mininet switch.
2840
2841 Returns a json structure containing information about the
2842 ports of the given switch.
2843 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002844 try:
2845 response = self.getInterfaces( nodeName )
2846 # TODO: Sanity check on response. log if no such switch exists
2847 ports = []
2848 for line in response.split( "\n" ):
2849 if not line.startswith( "name=" ):
2850 continue
2851 portVars = {}
2852 for var in line.split( "," ):
2853 key, value = var.split( "=" )
2854 portVars[ key ] = value
2855 isUp = portVars.pop( 'enabled', "True" )
2856 isUp = "True" in isUp
2857 if verbose:
2858 main.log.info( "Reading switch port %s(%s)" %
2859 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2860 mac = portVars[ 'mac' ]
2861 if mac == 'None':
2862 mac = None
2863 ips = []
2864 ip = portVars[ 'ip' ]
2865 if ip == 'None':
2866 ip = None
2867 ips.append( ip )
2868 name = portVars[ 'name' ]
2869 if name == 'None':
2870 name = None
2871 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2872 if name == 'lo':
2873 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2874 else:
2875 portNo = re.search( portRe, name ).group( 'port' )
2876 ports.append( { 'of_port': portNo,
2877 'mac': str( mac ).replace( '\'', '' ),
2878 'name': name,
2879 'ips': ips,
2880 'enabled': isUp } )
2881 return ports
2882 except pexpect.EOF:
2883 main.log.error( self.name + ": EOF exception found" )
2884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002885 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002886 except Exception:
2887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002888 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002889
You Wangdb8cd0a2016-05-26 15:19:45 -07002890 def getOVSPorts( self, nodeName ):
2891 """
2892 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2893
2894 Returns a list of dictionaries containing information about each
2895 port of the given switch.
2896 """
2897 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2898 try:
2899 response = self.execute(
2900 cmd=command,
2901 prompt="mininet>",
2902 timeout=10 )
2903 ports = []
2904 if response:
2905 for line in response.split( "\n" ):
2906 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2907 # Example port:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002908 # 1(s1-eth1): addr:ae:60:72:77:55:51
You Wangdb8cd0a2016-05-26 15:19:45 -07002909 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2910 result = re.search( pattern, line )
2911 if result:
2912 index = result.group( 'index' )
2913 name = result.group( 'name' )
2914 # This port number is extracted from port name
2915 port = result.group( 'port' )
2916 mac = result.group( 'mac' )
2917 ports.append( { 'index': index,
2918 'name': name,
2919 'port': port,
2920 'mac': mac } )
2921 return ports
2922 except pexpect.EOF:
2923 main.log.error( self.name + ": EOF exception found" )
2924 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002925 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002926 except Exception:
2927 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07002929
Devin Lima7cfdbd2017-09-29 15:02:22 -07002930 def getSwitches( self, verbose=False, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07002931 """
2932 Read switches from Mininet.
2933
2934 Returns a dictionary whose keys are the switch names and the value is
2935 a dictionary containing information about the switch.
2936 """
Jon Halla22481b2015-07-28 17:46:01 -07002937 # NOTE: To support new Mininet switch classes, just append the new
2938 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002939
Jon Halla22481b2015-07-28 17:46:01 -07002940 # Regex patterns to parse 'dump' output
2941 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002942 # <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 -07002943 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002944 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2945 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2946 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002947 try:
2948 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2949 swRE = r"<(?P<class>" + switchClasses + r")" +\
2950 r"(?P<options>\{.*\})?\s" +\
2951 r"(?P<name>[^:]+)\:\s" +\
2952 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2953 r"\spid=(?P<pid>(\d)+)"
2954 # Update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07002955 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002956 output = {}
2957 dump = self.dump().split( "\n" )
2958 for line in dump:
2959 result = re.search( swRE, line, re.I )
2960 if result:
2961 name = result.group( 'name' )
2962 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2963 pid = result.group( 'pid' )
2964 swClass = result.group( 'class' )
2965 options = result.group( 'options' )
2966 if verbose:
2967 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2968 ports = self.getPorts( name )
2969 output[ name ] = { "dpid": dpid,
2970 "ports": ports,
2971 "swClass": swClass,
2972 "pid": pid,
2973 "options": options }
2974 return output
2975 except pexpect.EOF:
2976 main.log.error( self.name + ": EOF exception found" )
2977 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002978 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002979 except Exception:
2980 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002981 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07002982
Jon Hallab611372018-02-21 15:26:05 -08002983 def getHosts( self, verbose=False, updateTimeout=1000,
2984 hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
2985 getInterfaces=True ):
Jon Hallafa8a472015-06-12 14:02:42 -07002986 """
2987 Read hosts from Mininet.
You Wang53dba1e2018-02-02 17:45:44 -08002988 Optional:
2989 hostClass: it is used to match the class of the mininet host. It
2990 can be a string or a list of strings.
Jon Hallafa8a472015-06-12 14:02:42 -07002991 Returns a dictionary whose keys are the host names and the value is
2992 a dictionary containing information about the host.
2993 """
2994 # Regex patterns to parse dump output
2995 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002996 # <Host h1: pid=12725>
2997 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2998 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2999 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003000 # NOTE: Does not correctly match hosts with multi-links
3001 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3002 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003003 try:
You Wang53dba1e2018-02-02 17:45:44 -08003004 if not isinstance( hostClass, types.ListType ):
3005 hostClass = [ str( hostClass ) ]
3006 classRE = "(" + "|".join([c for c in hostClass]) + ")"
Jon Hallab611372018-02-21 15:26:05 -08003007 ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
3008 ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
3009 hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003010 # update mn port info
Devin Lima7cfdbd2017-09-29 15:02:22 -07003011 self.update( updateTimeout )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003012 # Get mininet dump
3013 dump = self.dump().split( "\n" )
3014 hosts = {}
3015 for line in dump:
You Wang53dba1e2018-02-02 17:45:44 -08003016 result = re.search( hostRE, line )
3017 if result:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003018 name = result.group( 'name' )
3019 interfaces = []
You Wang79f5c5b2018-03-14 11:10:44 -07003020 if getInterfaces:
3021 response = self.getInterfaces( name )
3022 # Populate interface info
3023 for line in response.split( "\n" ):
3024 if line.startswith( "name=" ):
3025 portVars = {}
3026 for var in line.split( "," ):
3027 key, value = var.split( "=" )
3028 portVars[ key ] = value
3029 isUp = portVars.pop( 'enabled', "True" )
3030 isUp = "True" in isUp
3031 if verbose:
3032 main.log.info( "Reading host port %s(%s)" %
3033 ( portVars[ 'name' ],
3034 portVars[ 'mac' ] ) )
3035 mac = portVars[ 'mac' ]
3036 if mac == 'None':
3037 mac = None
3038 ips = []
3039 ip = portVars[ 'ip' ]
3040 if ip == 'None':
3041 ip = None
3042 ips.append( ip )
3043 intfName = portVars[ 'name' ]
3044 if name == 'None':
3045 name = None
3046 interfaces.append( {
3047 "name": intfName,
3048 "ips": ips,
3049 "mac": str( mac ),
3050 "isUp": isUp } )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003051 hosts[ name ] = { "interfaces": interfaces }
3052 return hosts
3053 except pexpect.EOF:
3054 main.log.error( self.name + ": EOF exception found" )
3055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003056 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003057 except Exception:
3058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003059 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003060
Devin Lima7cfdbd2017-09-29 15:02:22 -07003061 def getLinks( self, timeout=20, updateTimeout=1000 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003062 """
3063 Gathers information about current Mininet links. These links may not
3064 be up if one of the ports is down.
3065
3066 Returns a list of dictionaries with link endpoints.
3067
3068 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003069 { 'node1': str( node1 name )
3070 'node2': str( node2 name )
3071 'port1': str( port1 of_port )
3072 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003073 Note: The port number returned is the eth#, not necessarily the of_port
3074 number. In Mininet, for OVS switch, these should be the same. For
3075 hosts, this is just the eth#.
3076 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003077 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003078 self.update()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003079 response = self.links( timeout=timeout ).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003080
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003081 # Examples:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003082 # s1-eth3<->s2-eth1 (OK OK)
3083 # s13-eth3<->h27-eth0 (OK OK)
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003084 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3085 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3086 links = []
3087 for line in response:
3088 match = re.search( linkRE, line )
3089 if match:
3090 node1 = match.group( 'node1' )
3091 node2 = match.group( 'node2' )
3092 port1 = match.group( 'port1' )
3093 port2 = match.group( 'port2' )
3094 links.append( { 'node1': node1,
3095 'node2': node2,
3096 'port1': port1,
3097 'port2': port2 } )
3098 return links
3099
3100 except pexpect.EOF:
3101 main.log.error( self.name + ": EOF exception found" )
3102 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003103 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003104 except Exception:
3105 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003106 main.cleanAndExit()
Jon Hallafa8a472015-06-12 14:02:42 -07003107
3108 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003109 """
3110 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003111 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003112
Jon Hallafa8a472015-06-12 14:02:42 -07003113 Dependencies:
3114 1. numpy - "sudo pip install numpy"
3115 """
3116 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003117 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003118 try:
3119 mnDPIDs = []
3120 for swName, switch in switches.iteritems():
3121 mnDPIDs.append( switch[ 'dpid' ].lower() )
3122 mnDPIDs.sort()
3123 if switchesJson == "": # if rest call fails
3124 main.log.error(
3125 self.name +
3126 ".compareSwitches(): Empty JSON object given from ONOS" )
3127 return main.FALSE
3128 onos = switchesJson
3129 onosDPIDs = []
3130 for switch in onos:
3131 if switch[ 'available' ]:
3132 onosDPIDs.append(
3133 switch[ 'id' ].replace(
3134 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003135 '' ).replace(
3136 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003137 '' ).lower() )
3138 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003139
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003140 if mnDPIDs != onosDPIDs:
3141 switchResults = main.FALSE
3142 main.log.error( "Switches in MN but not in ONOS:" )
3143 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3144 main.log.error( str( list1 ) )
3145 main.log.error( "Switches in ONOS but not in MN:" )
3146 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3147 main.log.error( str( list2 ) )
3148 else: # list of dpid's match in onos and mn
3149 switchResults = main.TRUE
3150 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003151
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003152 # FIXME: this does not look for extra ports in ONOS, only checks that
3153 # ONOS has what is in MN
3154 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003155
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003156 # PORTS
3157 for name, mnSwitch in switches.iteritems():
3158 mnPorts = []
3159 onosPorts = []
3160 switchResult = main.TRUE
3161 for port in mnSwitch[ 'ports' ]:
3162 if port[ 'enabled' ]:
3163 mnPorts.append( int( port[ 'of_port' ] ) )
3164 for onosSwitch in portsJson:
3165 if onosSwitch[ 'device' ][ 'available' ]:
3166 if onosSwitch[ 'device' ][ 'id' ].replace(
3167 ':',
3168 '' ).replace(
3169 "of",
3170 '' ) == mnSwitch[ 'dpid' ]:
3171 for port in onosSwitch[ 'ports' ]:
3172 if port[ 'isEnabled' ]:
Jeremy Ronquillob2ca25e2017-06-15 08:51:23 -07003173 if port[ 'port' ].lower() == 'local':
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003174 # onosPorts.append( 'local' )
3175 onosPorts.append( long( uint64( -2 ) ) )
3176 else:
3177 onosPorts.append( int( port[ 'port' ] ) )
3178 break
3179 mnPorts.sort( key=float )
3180 onosPorts.sort( key=float )
3181
3182 mnPortsLog = mnPorts
3183 onosPortsLog = onosPorts
3184 mnPorts = [ x for x in mnPorts ]
3185 onosPorts = [ x for x in onosPorts ]
3186
3187 # TODO: handle other reserved port numbers besides LOCAL
3188 # NOTE: Reserved ports
3189 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3190 # long( uint64( -2 ) )
3191 for mnPort in mnPortsLog:
3192 if mnPort in onosPorts:
3193 # don't set results to true here as this is just one of
3194 # many checks and it might override a failure
3195 mnPorts.remove( mnPort )
3196 onosPorts.remove( mnPort )
3197
3198 # NOTE: OVS reports this as down since there is no link
3199 # So ignoring these for now
3200 # TODO: Come up with a better way of handling these
3201 if 65534 in mnPorts:
3202 mnPorts.remove( 65534 )
3203 if long( uint64( -2 ) ) in onosPorts:
3204 onosPorts.remove( long( uint64( -2 ) ) )
3205 if len( mnPorts ): # the ports of this switch don't match
3206 switchResult = main.FALSE
3207 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3208 if len( onosPorts ): # the ports of this switch don't match
3209 switchResult = main.FALSE
3210 main.log.warn(
3211 "Ports in ONOS but not MN: " +
3212 str( onosPorts ) )
3213 if switchResult == main.FALSE:
3214 main.log.error(
3215 "The list of ports for switch %s(%s) does not match:" %
3216 ( name, mnSwitch[ 'dpid' ] ) )
3217 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3218 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3219 portsResults = portsResults and switchResult
3220 finalResults = finalResults and portsResults
3221 return finalResults
3222 except pexpect.EOF:
3223 main.log.error( self.name + ": EOF exception found" )
3224 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003225 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003226 except Exception:
3227 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003228 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003229
Jon Hallafa8a472015-06-12 14:02:42 -07003230 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003231 """
3232 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003233 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003234
Jon Hallafa8a472015-06-12 14:02:42 -07003235 """
Jon Hall7eb38402015-01-08 17:19:54 -08003236 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003237 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003238 try:
3239 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003240
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003241 mnLinks = []
3242 for l in links:
3243 try:
3244 node1 = switches[ l[ 'node1' ] ]
3245 node2 = switches[ l[ 'node2' ] ]
3246 enabled = True
3247 for port in node1[ 'ports' ]:
3248 if port[ 'of_port' ] == l[ 'port1' ]:
3249 enabled = enabled and port[ 'enabled' ]
3250 for port in node2[ 'ports' ]:
3251 if port[ 'of_port' ] == l[ 'port2' ]:
3252 enabled = enabled and port[ 'enabled' ]
3253 if enabled:
3254 mnLinks.append( l )
3255 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003256 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003257 if 2 * len( mnLinks ) == len( onos ):
3258 linkResults = main.TRUE
3259 else:
3260 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003261 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003262 "Mininet has " + str( len( mnLinks ) ) +
3263 " bidirectional links and ONOS has " +
3264 str( len( onos ) ) + " unidirectional links" )
3265
3266 # iterate through MN links and check if an ONOS link exists in
3267 # both directions
3268 for link in mnLinks:
3269 # TODO: Find a more efficient search method
3270 node1 = None
3271 port1 = None
3272 node2 = None
3273 port2 = None
3274 firstDir = main.FALSE
3275 secondDir = main.FALSE
3276 for swName, switch in switches.iteritems():
3277 if swName == link[ 'node1' ]:
3278 node1 = switch[ 'dpid' ]
3279 for port in switch[ 'ports' ]:
3280 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3281 port1 = port[ 'of_port' ]
3282 if node1 is not None and node2 is not None:
3283 break
3284 if swName == link[ 'node2' ]:
3285 node2 = switch[ 'dpid' ]
3286 for port in switch[ 'ports' ]:
3287 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3288 port2 = port[ 'of_port' ]
3289 if node1 is not None and node2 is not None:
3290 break
3291
3292 for onosLink in onos:
3293 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3294 ":", '' ).replace( "of", '' )
3295 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3296 ":", '' ).replace( "of", '' )
3297 onosPort1 = onosLink[ 'src' ][ 'port' ]
3298 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3299
3300 # check onos link from node1 to node2
3301 if str( onosNode1 ) == str( node1 ) and str(
3302 onosNode2 ) == str( node2 ):
3303 if int( onosPort1 ) == int( port1 ) and int(
3304 onosPort2 ) == int( port2 ):
3305 firstDir = main.TRUE
3306 else:
Jon Hallab611372018-02-21 15:26:05 -08003307 # The right switches, but wrong ports, could be
3308 # another link between these devices, or onos
3309 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003310 main.log.warn(
3311 'The port numbers do not match for ' +
3312 str( link ) +
3313 ' between ONOS and MN. When checking ONOS for ' +
3314 'link %s/%s -> %s/%s' %
3315 ( node1, port1, node2, port2 ) +
3316 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003317 ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
3318 '. This could be another link between these devices' +
3319 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003320
3321 # check onos link from node2 to node1
3322 elif ( str( onosNode1 ) == str( node2 ) and
3323 str( onosNode2 ) == str( node1 ) ):
3324 if ( int( onosPort1 ) == int( port2 )
3325 and int( onosPort2 ) == int( port1 ) ):
3326 secondDir = main.TRUE
3327 else:
Jon Hallab611372018-02-21 15:26:05 -08003328 # The right switches, but wrong ports, could be
3329 # another link between these devices, or onos
3330 # discovered the links incorrectly
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003331 main.log.warn(
3332 'The port numbers do not match for ' +
3333 str( link ) +
3334 ' between ONOS and MN. When checking ONOS for ' +
3335 'link %s/%s -> %s/%s' %
3336 ( node1, port1, node2, port2 ) +
3337 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallab611372018-02-21 15:26:05 -08003338 ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
3339 '. This could be another link between these devices' +
3340 ' or a incorrectly discoved link' )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003341 else: # this is not the link you're looking for
3342 pass
3343 if not firstDir:
3344 main.log.error(
3345 'ONOS does not have the link %s/%s -> %s/%s' %
3346 ( node1, port1, node2, port2 ) )
3347 if not secondDir:
3348 main.log.error(
3349 'ONOS does not have the link %s/%s -> %s/%s' %
3350 ( node2, port2, node1, port1 ) )
3351 linkResults = linkResults and firstDir and secondDir
3352 return linkResults
3353 except pexpect.EOF:
3354 main.log.error( self.name + ": EOF exception found" )
3355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003356 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003357 except Exception:
3358 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003359 main.cleanAndExit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003360
Jon Hallafa8a472015-06-12 14:02:42 -07003361 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003362 """
Jon Hallafa8a472015-06-12 14:02:42 -07003363 Compare mn and onos Hosts.
3364 Since Mininet hosts are quiet, ONOS will only know of them when they
3365 speak. For this reason, we will only check that the hosts in ONOS
3366 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003367
Jon Hallafa8a472015-06-12 14:02:42 -07003368 Arguments:
3369 hostsJson: parsed json object from the onos hosts api
3370 Returns:
3371 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003372 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003373 try:
3374 hostResults = main.TRUE
3375 for onosHost in hostsJson:
3376 onosMAC = onosHost[ 'mac' ].lower()
3377 match = False
3378 for mnHost, info in hosts.iteritems():
3379 for mnIntf in info[ 'interfaces' ]:
3380 if onosMAC == mnIntf[ 'mac' ].lower():
3381 match = True
3382 for ip in mnIntf[ 'ips' ]:
3383 if ip in onosHost[ 'ipAddresses' ]:
3384 pass # all is well
3385 else:
3386 # misssing ip
3387 main.log.error( "ONOS host " +
3388 onosHost[ 'id' ] +
3389 " has a different IP(" +
3390 str( onosHost[ 'ipAddresses' ] ) +
3391 ") than the Mininet host(" +
3392 str( ip ) +
3393 ")." )
3394 output = json.dumps(
3395 onosHost,
3396 sort_keys=True,
3397 indent=4,
3398 separators=( ',', ': ' ) )
3399 main.log.info( output )
3400 hostResults = main.FALSE
3401 if not match:
3402 hostResults = main.FALSE
3403 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3404 "corresponding Mininet host." )
3405 output = json.dumps( onosHost,
3406 sort_keys=True,
3407 indent=4,
3408 separators=( ',', ': ' ) )
3409 main.log.info( output )
3410 return hostResults
3411 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003412 main.log.error( self.name + ": EOF exception found" )
3413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003414 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003415 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003416 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003417 main.cleanAndExit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003418
You Wang53dba1e2018-02-02 17:45:44 -08003419 def verifyHostIp( self, hostList=[], prefix="" ):
3420 """
3421 Description:
3422 Verify that all hosts have IP address assigned to them
3423 Optional:
3424 hostList: If specified, verifications only happen to the hosts
3425 in hostList
3426 prefix: at least one of the ip address assigned to the host
3427 needs to have the specified prefix
3428 Returns:
3429 main.TRUE if all hosts have specific IP address assigned;
3430 main.FALSE otherwise
3431 """
3432 try:
You Wang79f5c5b2018-03-14 11:10:44 -07003433 hosts = self.getHosts( getInterfaces=False )
You Wang53dba1e2018-02-02 17:45:44 -08003434 if not hostList:
3435 hostList = hosts.keys()
3436 for hostName in hosts.keys():
3437 if hostName not in hostList:
3438 continue
3439 ipList = []
3440 self.handle.sendline( str( hostName ) + " ip a" )
3441 self.handle.expect( "mininet>" )
3442 ipa = self.handle.before
3443 ipv4Pattern = r'inet ((?:[0-9]{1,3}\.){3}[0-9]{1,3})/'
3444 ipList += re.findall( ipv4Pattern, ipa )
3445 # It's tricky to make regex for IPv6 addresses and this one is simplified
3446 ipv6Pattern = r'inet6 ((?:[0-9a-fA-F]{1,4})?(?:[:0-9a-fA-F]{1,4}){1,7}(?:::)?(?:[:0-9a-fA-F]{1,4}){1,7})/'
3447 ipList += re.findall( ipv6Pattern, ipa )
3448 main.log.debug( self.name + ": IP list on host " + str( hostName ) + ": " + str( ipList ) )
3449 if not ipList:
3450 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostName ) )
3451 else:
3452 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
3453 main.log.warn( self.name + ": None of the IPs on host " + str( hostName ) + " has prefix " + str( prefix ) )
3454 else:
3455 main.log.debug( self.name + ": Found matching IP on host " + str( hostName ) )
3456 hostList.remove( hostName )
3457 return main.FALSE if hostList else main.TRUE
3458 except KeyError:
3459 main.log.exception( self.name + ": host data not as expected: " + hosts )
3460 return None
3461 except pexpect.EOF:
3462 main.log.error( self.name + ": EOF exception found" )
3463 main.log.error( self.name + ": " + self.handle.before )
3464 main.cleanAndExit()
3465 except Exception:
3466 main.log.exception( self.name + ": Uncaught exception" )
3467 return None
3468
Jon Hallafa8a472015-06-12 14:02:42 -07003469 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003470 """
3471 Returns a list of all hosts
3472 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003473 try:
3474 self.handle.sendline( "" )
3475 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003476
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003477 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3478 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003479
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003480 handlePy = self.handle.before
3481 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3482 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003483
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003484 self.handle.sendline( "" )
3485 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003486
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003487 hostStr = handlePy.replace( "]", "" )
3488 hostStr = hostStr.replace( "'", "" )
3489 hostStr = hostStr.replace( "[", "" )
3490 hostStr = hostStr.replace( " ", "" )
3491 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003492
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003493 return hostList
3494 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003495 main.log.error( self.name + ": TIMEOUT exception found" )
3496 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003497 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003498 except pexpect.EOF:
3499 main.log.error( self.name + ": EOF exception found" )
3500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003501 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003502 except Exception:
3503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003504 main.cleanAndExit()
adminbae64d82013-08-01 10:50:15 -07003505
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003506 def getSwitch( self ):
3507 """
3508 Returns a list of all switches
3509 Again, don't ask question just use it...
3510 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003511 try:
3512 # get host list...
3513 hostList = self.getHosts()
3514 # Make host set
3515 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003516
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003517 # Getting all the nodes in mininet
3518 self.handle.sendline( "" )
3519 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003520
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003521 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3522 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003523
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003524 handlePy = self.handle.before
3525 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3526 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003527
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003528 self.handle.sendline( "" )
3529 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003530
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003531 nodesStr = handlePy.replace( "]", "" )
3532 nodesStr = nodesStr.replace( "'", "" )
3533 nodesStr = nodesStr.replace( "[", "" )
3534 nodesStr = nodesStr.replace( " ", "" )
3535 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003536
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003537 nodesSet = set( nodesList )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003538 # discarding default controller(s) node
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003539 nodesSet.discard( 'c0' )
3540 nodesSet.discard( 'c1' )
3541 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003542
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003543 switchSet = nodesSet - hostSet
3544 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003545
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003546 return switchList
3547 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003548 main.log.error( self.name + ": TIMEOUT exception found" )
3549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003550 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003551 except pexpect.EOF:
3552 main.log.error( self.name + ": EOF exception found" )
3553 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003554 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003555 except Exception:
3556 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003557 main.cleanAndExit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003558
You Wangdb8cd0a2016-05-26 15:19:45 -07003559 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3560 """
3561 Return a dictionary which describes the latest Mininet topology data as a
3562 graph.
3563 An example of the dictionary:
3564 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3565 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3566 Each vertex should at least have an 'edges' attribute which describes the
3567 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003568 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07003569 list of attributes.
3570 An example of the edges dictionary:
3571 'edges': { vertex2: { 'port': ..., 'weight': ... },
3572 vertex3: { 'port': ..., 'weight': ... } }
3573 If useId == True, dpid/mac will be used instead of names to identify
3574 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3575 topology.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003576 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07003577 in topology data.
3578 Note that link or switch that are brought down by 'link x x down' or 'switch
3579 x down' commands still show in the output of Mininet CLI commands such as
3580 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3581 recommended to use delLink() or delSwitch functions to simulate link/switch
3582 down, and addLink() or addSwitch to add them back.
3583 """
3584 graphDict = {}
3585 try:
3586 links = self.getLinks( timeout=timeout )
3587 portDict = {}
3588 if useId:
3589 switches = self.getSwitches()
3590 if includeHost:
3591 hosts = self.getHosts()
3592 for link in links:
3593 # FIXME: support 'includeHost' argument
3594 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3595 continue
3596 nodeName1 = link[ 'node1' ]
3597 nodeName2 = link[ 'node2' ]
3598 port1 = link[ 'port1' ]
3599 port2 = link[ 'port2' ]
3600 # Loop for two nodes
3601 for i in range( 2 ):
3602 # Get port index from OVS
3603 # The index extracted from port name may be inconsistent with ONOS
3604 portIndex = -1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003605 if nodeName1 not in portDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003606 portList = self.getOVSPorts( nodeName1 )
3607 if len( portList ) == 0:
3608 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3609 return None
3610 portDict[ nodeName1 ] = portList
3611 for port in portDict[ nodeName1 ]:
3612 if port[ 'port' ] == port1:
3613 portIndex = port[ 'index' ]
3614 break
3615 if portIndex == -1:
3616 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3617 return None
3618 if useId:
3619 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3620 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3621 else:
3622 node1 = nodeName1
3623 node2 = nodeName2
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003624 if node1 not in graphDict.keys():
You Wangdb8cd0a2016-05-26 15:19:45 -07003625 if useId:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003626 graphDict[ node1 ] = { 'edges': {},
3627 'dpid': switches[ nodeName1 ][ 'dpid' ],
3628 'name': nodeName1,
3629 'ports': switches[ nodeName1 ][ 'ports' ],
3630 'swClass': switches[ nodeName1 ][ 'swClass' ],
3631 'pid': switches[ nodeName1 ][ 'pid' ],
3632 'options': switches[ nodeName1 ][ 'options' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07003633 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003634 graphDict[ node1 ] = { 'edges': {} }
You Wangdb8cd0a2016-05-26 15:19:45 -07003635 else:
3636 # Assert node2 is not connected to any current links of node1
3637 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003638 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port': portIndex }
You Wangdb8cd0a2016-05-26 15:19:45 -07003639 # Swap two nodes/ports
3640 nodeName1, nodeName2 = nodeName2, nodeName1
3641 port1, port2 = port2, port1
3642 return graphDict
3643 except KeyError:
3644 main.log.exception( self.name + ": KeyError exception found" )
3645 return None
3646 except AssertionError:
3647 main.log.exception( self.name + ": AssertionError exception found" )
3648 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003649 except pexpect.EOF:
3650 main.log.error( self.name + ": EOF exception found" )
3651 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003652 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003653 except Exception:
3654 main.log.exception( self.name + ": Uncaught exception" )
3655 return None
3656
Devin Lima7cfdbd2017-09-29 15:02:22 -07003657 def update( self, timeout=1000 ):
Jon Hall7eb38402015-01-08 17:19:54 -08003658 """
3659 updates the port address and status information for
3660 each port in mn"""
3661 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003662 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003663 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003664 self.handle.sendline( "" )
3665 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003666
Jon Hall7eb38402015-01-08 17:19:54 -08003667 self.handle.sendline( "update" )
Devin Lima7cfdbd2017-09-29 15:02:22 -07003668 self.handle.expect( "mininet>", timeout )
Jon Hall38481722014-11-04 16:50:05 -05003669
Jon Hall7eb38402015-01-08 17:19:54 -08003670 self.handle.sendline( "" )
3671 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003672
Jon Hallb1290e82014-11-18 16:17:48 -05003673 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003674 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003675 main.log.error( self.name + ": TIMEOUT exception found" )
3676 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003677 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003678 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003679 main.log.error( self.name + ": EOF exception found" )
3680 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003681 main.cleanAndExit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003682 except Exception:
3683 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003684 main.cleanAndExit()
Jon Hallb1290e82014-11-18 16:17:48 -05003685
Jon Halld80cc142015-07-06 13:36:05 -07003686 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003687 """
3688 Add vlan tag to a host.
3689 Dependencies:
3690 This class depends on the "vlan" package
3691 $ sudo apt-get install vlan
3692 Configuration:
3693 Load the 8021q module into the kernel
3694 $sudo modprobe 8021q
3695
3696 To make this setup permanent:
3697 $ sudo su -c 'echo "8021q" >> /etc/modules'
3698 """
3699 if self.handle:
3700 try:
Jon Halld80cc142015-07-06 13:36:05 -07003701 # get the ip address of the host
3702 main.log.info( "Get the ip address of the host" )
3703 ipaddr = self.getIPAddress( host )
3704 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003705
Jon Halld80cc142015-07-06 13:36:05 -07003706 # remove IP from interface intf
3707 # Ex: h1 ifconfig h1-eth0 inet 0
3708 main.log.info( "Remove IP from interface " )
3709 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3710 self.handle.sendline( cmd2 )
3711 self.handle.expect( "mininet>" )
3712 response = self.handle.before
3713 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003714
Jon Halld80cc142015-07-06 13:36:05 -07003715 # create VLAN interface
3716 # Ex: h1 vconfig add h1-eth0 100
3717 main.log.info( "Create Vlan" )
3718 cmd3 = host + " vconfig add " + intf + " " + vlan
3719 self.handle.sendline( cmd3 )
3720 self.handle.expect( "mininet>" )
3721 response = self.handle.before
3722 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003723
Jon Halld80cc142015-07-06 13:36:05 -07003724 # assign the host's IP to the VLAN interface
3725 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3726 main.log.info( "Assign the host IP to the vlan interface" )
3727 vintf = intf + "." + vlan
3728 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3729 self.handle.sendline( cmd4 )
3730 self.handle.expect( "mininet>" )
3731 response = self.handle.before
3732 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003733
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08003734 # update Mininet node variables
3735 main.log.info( "Update Mininet node variables" )
3736 cmd5 = "px %s.defaultIntf().name='%s'" % ( host, vintf )
3737 self.handle.sendline( cmd5 )
3738 self.handle.expect( "mininet>" )
3739 response = self.handle.before
3740 main.log.info( "====> %s ", response )
3741
3742 cmd6 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, vintf, host )
3743 self.handle.sendline( cmd6 )
3744 self.handle.expect( "mininet>" )
3745 response = self.handle.before
3746 main.log.info( "====> %s ", response )
3747
3748 return main.TRUE
3749 except pexpect.TIMEOUT:
3750 main.log.error( self.name + ": TIMEOUT exception found" )
3751 main.log.error( self.name + ": " + self.handle.before )
3752 main.cleanAndExit()
3753 except pexpect.EOF:
3754 main.log.error( self.name + ": EOF exception found" )
3755 main.log.error( self.name + ": " + self.handle.before )
3756 return main.FALSE
3757 except Exception:
3758 main.log.exception( self.name + ": Uncaught exception!" )
3759 return main.FALSE
3760
3761 def removeVLAN( self, host, intf ):
3762 """
3763 Remove vlan tag from a host.
3764 Dependencies:
3765 This class depends on the "vlan" package
3766 $ sudo apt-get install vlan
3767 Configuration:
3768 Load the 8021q module into the kernel
3769 $sudo modprobe 8021q
3770
3771 To make this setup permanent:
3772 $ sudo su -c 'echo "8021q" >> /etc/modules'
3773 """
3774 if self.handle:
3775 try:
3776 # get the ip address of the host
3777 main.log.info( "Get the ip address of the host" )
3778 ipaddr = self.getIPAddress( host )
3779
3780 # remove VLAN interface
3781 # Ex: h1 vconfig rem h1-eth0.100
3782 main.log.info( "Remove Vlan interface" )
3783 cmd2 = host + " vconfig rem " + intf
3784 self.handle.sendline( cmd2 )
3785 self.handle.expect( "mininet>" )
3786 response = self.handle.before
3787 main.log.info( "====> %s ", response )
3788
3789 # assign the host's IP to the original interface
3790 # Ex: h1 ifconfig h1-eth0 inet 10.0.0.1
3791 main.log.info( "Assign the host IP to the original interface" )
3792 original_intf = intf.split(".")[0]
3793 cmd3 = host + " ifconfig " + original_intf + " " + " inet " + ipaddr
3794 self.handle.sendline( cmd3 )
3795 self.handle.expect( "mininet>" )
3796 response = self.handle.before
3797 main.log.info( "====> %s ", response )
3798
3799 # update Mininet node variables
3800 cmd4 = "px %s.defaultIntf().name='%s'" % ( host, original_intf )
3801 self.handle.sendline( cmd4 )
3802 self.handle.expect( "mininet>" )
3803 response = self.handle.before
3804 main.log.info( "====> %s ", response )
3805
3806 cmd5 = "px %s.nameToIntf['%s']=%s.defaultIntf()" % ( host, original_intf, host )
3807 self.handle.sendline( cmd5 )
3808 self.handle.expect( "mininet>" )
3809 response = self.handle.before
3810 main.log.info( "====> %s ", response )
3811
kaouthera3f13ca22015-05-05 15:01:41 -07003812 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003813 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003814 main.log.error( self.name + ": TIMEOUT exception found" )
3815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003816 main.cleanAndExit()
kaouthera3f13ca22015-05-05 15:01:41 -07003817 except pexpect.EOF:
3818 main.log.error( self.name + ": EOF exception found" )
3819 main.log.error( self.name + ": " + self.handle.before )
3820 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003821 except Exception:
3822 main.log.exception( self.name + ": Uncaught exception!" )
3823 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003824
Jon Hall892818c2015-10-20 17:58:34 -07003825 def createHostComponent( self, name ):
3826 """
3827 Creates a new mininet cli component with the same parameters as self.
3828 This new component is intended to be used to login to the hosts created
3829 by mininet.
3830
3831 Arguments:
3832 name - The string of the name of this component. The new component
3833 will be assigned to main.<name> .
3834 In addition, main.<name>.name = str( name )
3835 """
3836 try:
3837 # look to see if this component already exists
3838 getattr( main, name )
3839 except AttributeError:
3840 # namespace is clear, creating component
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003841 main.componentDictionary[ name ] = main.componentDictionary[ self.name ].copy()
3842 main.componentDictionary[ name ][ 'connect_order' ] = str( int( main.componentDictionary[ name ][ 'connect_order' ] ) + 1 )
Jon Hall892818c2015-10-20 17:58:34 -07003843 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003844 except pexpect.EOF:
3845 main.log.error( self.name + ": EOF exception found" )
3846 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003847 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003848 except Exception:
3849 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003850 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003851 else:
3852 # namespace is not clear!
3853 main.log.error( name + " component already exists!" )
3854 # FIXME: Should we exit here?
Devin Lim44075962017-08-11 10:56:37 -07003855 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003856
3857 def removeHostComponent( self, name ):
3858 """
3859 Remove host component
3860 Arguments:
3861 name - The string of the name of the component to delete.
3862 """
3863 try:
3864 # Get host component
3865 component = getattr( main, name )
3866 except AttributeError:
3867 main.log.error( "Component " + name + " does not exist." )
3868 return
3869 try:
3870 # Disconnect from component
3871 component.disconnect()
3872 # Delete component
3873 delattr( main, name )
3874 # Delete component from ComponentDictionary
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003875 del( main.componentDictionary[ name ] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003876 except pexpect.EOF:
3877 main.log.error( self.name + ": EOF exception found" )
3878 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003879 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003880 except Exception:
3881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003882 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003883
3884 def startHostCli( self, host=None ):
3885 """
3886 Use the mininet m utility to connect to the host's cli
3887 """
3888 # These are fields that can be used by scapy packets. Initialized to None
3889 self.hostIp = None
3890 self.hostMac = None
3891 try:
3892 if not host:
3893 host = self.name
3894 self.handle.sendline( self.home + "/util/m " + host )
Jeremy Ronquillo0f2008a2017-06-23 15:32:51 -07003895 self.handle.sendline( "cd" )
3896 self.handle.expect( self.hostPrompt )
3897 self.handle.sendline( "" )
Jon Hall892818c2015-10-20 17:58:34 -07003898 self.handle.expect( self.hostPrompt )
3899 return main.TRUE
3900 except pexpect.TIMEOUT:
3901 main.log.exception( self.name + ": Command timed out" )
3902 return main.FALSE
3903 except pexpect.EOF:
3904 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003905 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003906 except Exception:
3907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003908 main.cleanAndExit()
Jon Hall892818c2015-10-20 17:58:34 -07003909
YPZhang801d46d2016-08-08 13:26:28 -07003910 def changeInterfaceStatus( self, devicename, intf, status ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003911 '''
3912
YPZhang801d46d2016-08-08 13:26:28 -07003913 Args:
3914 devicename: switch name
3915 intf: port name on switch
3916 status: up or down
3917
3918 Returns: boolean to show success change status
3919
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003920 '''
YPZhang801d46d2016-08-08 13:26:28 -07003921 if status == "down" or status == "up":
3922 try:
3923 cmd = devicename + " ifconfig " + intf + " " + status
3924 self.handle.sendline( cmd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003925 self.handle.expect( "mininet>" )
YPZhang801d46d2016-08-08 13:26:28 -07003926 return main.TRUE
3927 except pexpect.TIMEOUT:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003928 main.log.exception( self.name + ": Command timed out" )
YPZhang801d46d2016-08-08 13:26:28 -07003929 return main.FALSE
3930 except pexpect.EOF:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003931 main.log.exception( self.name + ": connection closed." )
Devin Lim44075962017-08-11 10:56:37 -07003932 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003933 except TypeError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003934 main.log.exception( self.name + ": TypeError" )
Devin Lim44075962017-08-11 10:56:37 -07003935 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003936 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003938 main.cleanAndExit()
YPZhang801d46d2016-08-08 13:26:28 -07003939 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003940 main.log.warn( "Interface status should be up or down!" )
YPZhang801d46d2016-08-08 13:26:28 -07003941 return main.FALSE
3942
3943
adminbae64d82013-08-01 10:50:15 -07003944if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003945 sys.modules[ __name__ ] = MininetCliDriver()