blob: 90f79a95f280f035f65775308d5eb4a8bd21b270 [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 Songsterae01bba2016-07-11 15:39:17 -07004Modified 2016 by ON.Lab
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
Jon Hall1ccf82c2014-10-15 14:55:16 -040041from math import pow
adminbae64d82013-08-01 10:50:15 -070042from drivers.common.cli.emulatordriver import Emulator
You Wangdb8cd0a2016-05-26 15:19:45 -070043from core.graph import Graph
adminbae64d82013-08-01 10:50:15 -070044
Jon Hall7eb38402015-01-08 17:19:54 -080045
kelvin-onlab50907142015-04-01 13:37:45 -070046class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080047
48 """
49 MininetCliDriver is the basic driver which will handle
50 the Mininet functions"""
51 def __init__( self ):
52 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070053 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080054 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070055 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080056 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070057 self.flag = 0
Jon Hall892818c2015-10-20 17:58:34 -070058 # TODO: Refactor driver to use these everywhere
59 self.mnPrompt = "mininet>"
60 self.hostPrompt = "~#"
61 self.bashPrompt = "\$"
62 self.scapyPrompt = ">>>"
You Wangdb8cd0a2016-05-26 15:19:45 -070063 self.graph = Graph()
adminbae64d82013-08-01 10:50:15 -070064
Jon Hall7eb38402015-01-08 17:19:54 -080065 def connect( self, **connectargs ):
66 """
67 Here the main is the TestON instance after creating
68 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080069 try:
70 for key in connectargs:
71 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070072 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080073 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070074 for key in self.options:
75 if key == "home":
76 self.home = self.options[ 'home' ]
77 break
78 if self.home is None or self.home == "":
79 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070080
81 try:
Jon Hall892818c2015-10-20 17:58:34 -070082 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070083 self.ip_address = os.getenv( str( self.ip_address ) )
84 else:
85 main.log.info( self.name +
86 ": Trying to connect to " +
87 self.ip_address )
88
89 except KeyError:
90 main.log.info( "Invalid host name," +
91 " connecting to local host instead" )
92 self.ip_address = 'localhost'
93 except Exception as inst:
94 main.log.error( "Uncaught exception: " + str( inst ) )
95
kelvin-onlaba1484582015-02-02 15:46:20 -080096 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070097 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080098 self ).connect(
99 user_name=self.user_name,
100 ip_address=self.ip_address,
101 port=None,
102 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -0800103
kelvin-onlaba1484582015-02-02 15:46:20 -0800104 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -0800105 main.log.info( "Connection successful to the host " +
106 self.user_name +
107 "@" +
108 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800109 return main.TRUE
110 else:
111 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800112 self.user_name +
113 "@" +
114 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800115 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800116 return main.FALSE
117 except pexpect.EOF:
118 main.log.error( self.name + ": EOF exception found" )
119 main.log.error( self.name + ": " + self.handle.before )
120 main.cleanup()
121 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800122 except Exception:
123 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800124 main.cleanup()
125 main.exit()
126
kelvin-onlab10e8d392015-06-03 13:53:45 -0700127 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800128 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700129 Description:
130 Starts Mininet accepts a topology(.py) file and/or an optional
131 argument, to start the mininet, as a parameter.
132 Can also send regular mininet command to load up desired topology.
alison12f34c32016-06-10 14:39:21 -0700133 Eg. Pass in a string 'mn --topo=tree,3,3' to mnCmd
kelvin-onlabf512e942015-06-08 19:42:59 -0700134 Options:
135 topoFile = file path for topology file (.py)
136 args = extra option added when starting the topology from the file
137 mnCmd = Mininet command use to start topology
138 Returns:
139 main.TRUE if the mininet starts successfully, main.FALSE
140 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800141 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700142 try:
143 if self.handle:
144 # make sure old networks are cleaned up
145 main.log.info( self.name +
146 ": Clearing any residual state or processes" )
147 self.handle.sendline( "sudo mn -c" )
148 i = self.handle.expect( [ 'password\sfor\s',
149 'Cleanup\scomplete',
Jon Hallefbd9792015-03-05 16:11:36 -0800150 pexpect.EOF,
151 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700152 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800153 if i == 0:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700154 # Sudo asking for password
155 main.log.info( self.name + ": Sending sudo password" )
156 self.handle.sendline( self.pwd )
157 i = self.handle.expect( [ '%s:' % self.user,
158 '\$',
159 pexpect.EOF,
160 pexpect.TIMEOUT ],
161 timeout )
162 if i == 1:
163 main.log.info( self.name + ": Clean" )
Jon Hall689d8e42015-04-03 13:59:24 -0700164 elif i == 2:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700165 main.log.error( self.name + ": Connection terminated" )
166 elif i == 3: # timeout
167 main.log.error( self.name + ": Something while cleaning " +
168 "Mininet took too long... " )
169 # Craft the string to start mininet
170 cmdString = "sudo "
171 if not mnCmd:
172 if topoFile is None or topoFile == '': # If no file is given
173 main.log.info( self.name + ": building fresh Mininet" )
174 cmdString += "mn "
175 if args is None or args == '':
176 # If no args given, use args from .topo file
177 args = self.options[ 'arg1' ] +\
178 " " + self.options[ 'arg2' ] +\
179 " --mac --controller " +\
180 self.options[ 'controller' ] + " " +\
181 self.options[ 'arg3' ]
182 else: # else only use given args
183 pass
184 # TODO: allow use of topo args and method args?
185 else: # Use given topology file
186 main.log.info(
187 "Starting Mininet from topo file " +
188 topoFile )
189 cmdString += "-E python " + topoFile + " "
190 if args is None:
191 args = ''
192 # TODO: allow use of args from .topo file?
193 cmdString += args
194 else:
195 main.log.info( "Starting Mininet topology using '" + mnCmd +
196 "' command" )
197 cmdString += mnCmd
198 # Send the command and check if network started
199 self.handle.sendline( "" )
200 self.handle.expect( '\$' )
201 main.log.info( "Sending '" + cmdString + "' to " + self.name )
202 self.handle.sendline( cmdString )
203 while True:
204 i = self.handle.expect( [ 'mininet>',
205 'Exception',
206 '\*\*\*',
207 pexpect.EOF,
208 pexpect.TIMEOUT ],
209 timeout )
210 if i == 0:
211 main.log.info( self.name + ": Mininet built" )
212 return main.TRUE
213 elif i == 1:
214 response = str( self.handle.before +
215 self.handle.after )
216 self.handle.expect( '\$' )
217 response += str( self.handle.before +
218 self.handle.after )
219 main.log.error(
220 self.name +
221 ": Launching Mininet failed: " + response )
222 return main.FALSE
223 elif i == 2:
224 self.handle.expect( [ "\n",
225 pexpect.EOF,
226 pexpect.TIMEOUT ],
227 timeout )
228 main.log.info( self.handle.before )
229 elif i == 3:
230 main.log.error( self.name + ": Connection timeout" )
231 return main.FALSE
232 elif i == 4: # timeout
233 main.log.error(
234 self.name +
235 ": Something took too long... " )
236 return main.FALSE
237 # Why did we hit this part?
238 main.log.error( "startNet did not return correctly" )
239 return main.FASLE
240 else: # if no handle
241 main.log.error( self.name + ": Connection failed to the host " +
242 self.user_name + "@" + self.ip_address )
243 main.log.error( self.name + ": Failed to connect to the Mininet" )
244 return main.FALSE
245 except pexpect.TIMEOUT:
246 main.log.exception( self.name + ": TIMEOUT exception found while starting Mininet" )
247 main.log.error( self.name + ": " + self.handle.before )
adminbae64d82013-08-01 10:50:15 -0700248 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700249 except pexpect.EOF:
250 main.log.error( self.name + ": EOF exception found" )
251 main.log.error( self.name + ": " + self.handle.before )
252 main.cleanup()
253 main.exit()
254 except Exception:
255 main.log.exception( self.name + ": Uncaught exception!" )
256 main.cleanup()
257 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800258
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800259 def numSwitchesNlinks( self, topoType, depth, fanout ):
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700260 try:
261 if topoType == 'tree':
262 # In tree topology, if fanout arg is not given, by default it is 2
263 if fanout is None:
264 fanout = 2
265 k = 0
266 count = 0
267 while( k <= depth - 1 ):
268 count = count + pow( fanout, k )
269 k = k + 1
270 numSwitches = count
271 while( k <= depth - 2 ):
272 # depth-2 gives you only core links and not considering
273 # edge links as seen by ONOS. If all the links including
274 # edge links are required, do depth-1
275 count = count + pow( fanout, k )
276 k = k + 1
277 numLinks = count * fanout
278 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
279 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800280
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700281 elif topoType == 'linear':
282 # In linear topology, if fanout or numHostsPerSw is not given,
283 # by default it is 1
284 if fanout is None:
285 fanout = 1
286 numSwitches = depth
287 numHostsPerSw = fanout
288 totalNumHosts = numSwitches * numHostsPerSw
289 numLinks = totalNumHosts + ( numSwitches - 1 )
290 print "num_switches for %s(%d,%d) = %d and links=%d" %\
291 ( topoType, depth, fanout, numSwitches, numLinks )
292 topoDict = { "num_switches": int( numSwitches ),
293 "num_corelinks": int( numLinks ) }
294 return topoDict
295 except Exception:
296 main.log.exception( self.name + ": Uncaught exception!" )
297 main.cleanup()
298 main.exit()
Jon Hall1ccf82c2014-10-15 14:55:16 -0400299
kelvin-onlabd3b64892015-01-20 13:26:24 -0800300 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700301 """
302 Calculate the number of switches and links in a topo."""
303 # TODO: combine this function and numSwitchesNlinks
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700304 try:
305 argList = self.options[ 'arg1' ].split( "," )
306 topoArgList = argList[ 0 ].split( " " )
307 argList = map( int, argList[ 1: ] )
308 topoArgList = topoArgList[ 1: ] + argList
Jon Hall689d8e42015-04-03 13:59:24 -0700309
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700310 topoDict = self.numSwitchesNlinks( *topoArgList )
311 return topoDict
312 except Exception:
313 main.log.exception( self.name + ": Uncaught exception!" )
314 main.cleanup()
315 main.exit()
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 )
378 main.cleanup()
379 main.exit()
380 elif i == 3:
381 response += self.handle.before
382 main.log.error( self.name +
383 ": TIMEOUT exception found" )
384 main.log.error( self.name +
385 ": " +
386 str( response ) )
387 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800388 self.handle.send( "\x03" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700389 self.handle.expect( "Interrupt" )
390 self.handle.expect( "mininet>" )
391 break
392 pattern = "Results\:"
393 main.log.info( "Pingall output: " + str( response ) )
394 if re.search( pattern, response ):
395 main.log.info( self.name + ": Pingall finished with "
396 + str( failedPings ) + " failed pings" )
397 return returnValue
398 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700399 # NOTE: Send ctrl-c to make sure pingall is done
You Wangaf684312016-01-27 14:44:38 -0800400 self.handle.send( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700401 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700402 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700403 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700404 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700405 main.log.error( self.name + ": Connection failed to the host" )
406 main.cleanup()
407 main.exit()
408 except pexpect.TIMEOUT:
409 if response:
410 main.log.info( "Pingall output: " + str( response ) )
411 main.log.error( self.name + ": pexpect.TIMEOUT found" )
412 return main.FALSE
413 except pexpect.EOF:
414 main.log.error( self.name + ": EOF exception found" )
415 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500416 main.cleanup()
417 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700418
Jon Hall7eb38402015-01-08 17:19:54 -0800419 def fpingHost( self, **pingParams ):
420 """
421 Uses the fping package for faster pinging...
422 *requires fping to be installed on machine running mininet"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700423 try:
424 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
425 command = args[ "SRC" ] + \
426 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
427 self.handle.sendline( command )
428 self.handle.expect(
429 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
430 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
431 response = self.handle.before
432 if re.search( ":\s-", response ):
433 main.log.info( self.name + ": Ping fail" )
434 return main.FALSE
435 elif re.search( ":\s\d{1,2}\.\d\d", response ):
436 main.log.info( self.name + ": Ping good!" )
437 return main.TRUE
438 main.log.info( self.name + ": Install fping on mininet machine... " )
439 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700440 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700441 except Exception:
442 main.log.exception( self.name + ": Uncaught exception!" )
443 main.cleanup()
444 main.exit()
445
Jon Hallfbc828e2015-01-06 17:30:19 -0800446
Jon Hall3b489db2015-10-05 14:38:37 -0700447 def pingallHosts( self, hostList, wait=1 ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400448 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700449 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700450
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400451 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700452 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700453
454 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400455 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700456
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400457 Returns main.FALSE if one or more of hosts specified
458 cannot reach each other"""
Jon Hall3b489db2015-10-05 14:38:37 -0700459 wait = int( wait )
460 cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400461
462 try:
463 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700464
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400465 isReachable = main.TRUE
GlennRC6d506272015-09-25 11:36:07 -0700466 pingResponse = "IPv4 ping across specified hosts\n"
467 failedPings = 0
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400468 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700469 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400470 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700471 pingList = hostList[ :listIndex ] + \
472 hostList[ ( listIndex + 1 ): ]
GlennRCd10d3cc2015-09-24 12:47:16 -0700473
474 pingResponse += str(str(host) + " -> ")
475
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400476 for temp in pingList:
477 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700478 pingCmd = str( host ) + cmd + str( temp )
Jon Hall934576d2015-10-09 10:12:22 -0700479 self.handle.sendline( pingCmd )
480 self.handle.expect( "mininet>", timeout=wait + 1 )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400481 response = self.handle.before
482 if re.search( ',\s0\%\spacket\sloss', response ):
GlennRCd10d3cc2015-09-24 12:47:16 -0700483 pingResponse += str(" h" + str( temp[1:] ))
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400484 else:
GlennRCd10d3cc2015-09-24 12:47:16 -0700485 pingResponse += " X"
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400486 # One of the host to host pair is unreachable
487 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700488 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700489 pingResponse += "\n"
GlennRC6d506272015-09-25 11:36:07 -0700490 main.log.info( pingResponse + "Failed pings: " + str(failedPings) )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700491 return isReachable
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700492 except pexpect.TIMEOUT:
493 main.log.exception( self.name + ": TIMEOUT exception" )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700494 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400495 except pexpect.EOF:
496 main.log.error( self.name + ": EOF exception found" )
497 main.log.error( self.name + ": " + self.handle.before )
498 main.cleanup()
499 main.exit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700500 except Exception:
501 main.log.exception( self.name + ": Uncaught exception!" )
502 main.cleanup()
503 main.exit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400504
Jon Hall3b489db2015-10-05 14:38:37 -0700505 def pingIpv6Hosts( self, hostList, prefix='1000::', wait=1 ):
Hari Krishna9592fc82015-07-31 15:11:15 -0700506 """
Jon Hall3b489db2015-10-05 14:38:37 -0700507 IPv6 ping all hosts in hostList. If no prefix passed this will use
508 default prefix of 1000::
Hari Krishna9592fc82015-07-31 15:11:15 -0700509
Jon Hall3b489db2015-10-05 14:38:37 -0700510 Returns main.TRUE if all hosts specified can reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700511
Jon Hall3b489db2015-10-05 14:38:37 -0700512 Returns main.FALSE if one or more of hosts specified cannot reach each other
Hari Krishna9592fc82015-07-31 15:11:15 -0700513 """
514 try:
515 main.log.info( "Testing reachability between specified IPv6 hosts" )
516 isReachable = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -0700517 wait = int( wait )
518 cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
GlennRC6d506272015-09-25 11:36:07 -0700519 pingResponse = "IPv6 Pingall output:\n"
520 failedPings = 0
Hari Krishna9592fc82015-07-31 15:11:15 -0700521 for host in hostList:
522 listIndex = hostList.index( host )
523 # List of hosts to ping other than itself
524 pingList = hostList[ :listIndex ] + \
525 hostList[ ( listIndex + 1 ): ]
526
GlennRC2cf7d952015-09-11 16:32:13 -0700527 pingResponse += str(str(host) + " -> ")
528
Hari Krishna9592fc82015-07-31 15:11:15 -0700529 for temp in pingList:
530 # Current host pings all other hosts specified
Jon Hall439c8912016-04-15 02:22:03 -0700531 pingCmd = str( host ) + cmd + str( self.getIPAddress(temp,proto='IPv6') )
Jon Hall934576d2015-10-09 10:12:22 -0700532 self.handle.sendline( pingCmd )
533 self.handle.expect( "mininet>", timeout=wait + 1 )
Hari Krishna9592fc82015-07-31 15:11:15 -0700534 response = self.handle.before
535 if re.search( ',\s0\%\spacket\sloss', response ):
GlennRC2cf7d952015-09-11 16:32:13 -0700536 pingResponse += str(" h" + str( temp[1:] ))
Hari Krishna9592fc82015-07-31 15:11:15 -0700537 else:
GlennRC2cf7d952015-09-11 16:32:13 -0700538 pingResponse += " X"
Hari Krishna9592fc82015-07-31 15:11:15 -0700539 # One of the host to host pair is unreachable
540 isReachable = main.FALSE
GlennRC6d506272015-09-25 11:36:07 -0700541 failedPings += 1
GlennRCd10d3cc2015-09-24 12:47:16 -0700542 pingResponse += "\n"
GlennRC6d506272015-09-25 11:36:07 -0700543 main.log.info( pingResponse + "Failed pings: " + str(failedPings) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700544 return isReachable
545
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700546 except pexpect.TIMEOUT:
547 main.log.exception( self.name + ": TIMEOUT exception" )
548 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700549 except pexpect.EOF:
550 main.log.error( self.name + ": EOF exception found" )
551 main.log.error( self.name + ": " + self.handle.before )
552 main.cleanup()
553 main.exit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700554 except Exception:
555 main.log.exception( self.name + ": Uncaught exception!" )
556 main.cleanup()
557 main.exit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700558
Jon Hall7eb38402015-01-08 17:19:54 -0800559 def pingHost( self, **pingParams ):
560 """
Jon Hall3b489db2015-10-05 14:38:37 -0700561 Ping from one mininet host to another
562 Currently the only supported Params: SRC, TARGET, and WAIT
563 """
564 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
565 wait = args['WAIT']
566 wait = int( wait if wait else 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800567 command = args[ "SRC" ] + " ping " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700568 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Jon Hall6094a362014-04-11 14:46:56 -0700569 try:
Jon Hall61282e32015-03-19 11:34:11 -0700570 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800571 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700572 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
573 timeout=wait + 1 )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700574 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800575 main.log.error(
576 self.name +
577 ": timeout when waiting for response from mininet" )
578 main.log.error( "response: " + str( self.handle.before ) )
579 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700580 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800581 main.log.error(
582 self.name +
583 ": timeout when waiting for response from mininet" )
584 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700585 response = self.handle.before
Hari Krishna012a1c12015-08-25 14:23:58 -0700586 if re.search( ',\s0\%\spacket\sloss', response ):
587 main.log.info( self.name + ": no packets lost, host is reachable" )
588 return main.TRUE
589 else:
Jon Hall2c8959e2016-12-16 12:17:34 -0800590 main.log.warn(
Hari Krishna012a1c12015-08-25 14:23:58 -0700591 self.name +
592 ": PACKET LOST, HOST IS NOT REACHABLE" )
593 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800594 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800595 main.log.error( self.name + ": EOF exception found" )
596 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700597 main.cleanup()
598 main.exit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700599 except Exception:
600 main.log.exception( self.name + ": Uncaught exception!" )
601 main.cleanup()
602 main.exit()
603
604 def ping6pair( self, **pingParams ):
605 """
GlennRC2cf7d952015-09-11 16:32:13 -0700606 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700607 Currently the only supported Params are: SRC, TARGET, and WAIT
Hari Krishna012a1c12015-08-25 14:23:58 -0700608 FLOWLABEL and -I (src interface) will be added later after running some tests.
609 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
610 """
Jon Hall3b489db2015-10-05 14:38:37 -0700611 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
612 wait = args['WAIT']
613 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530614 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700615 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700616 try:
617 main.log.info( "Sending: " + command )
618 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700619 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
620 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700621 if i == 1:
622 main.log.error(
623 self.name +
624 ": timeout when waiting for response from mininet" )
625 main.log.error( "response: " + str( self.handle.before ) )
626 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
627 if i == 1:
628 main.log.error(
629 self.name +
630 ": timeout when waiting for response from mininet" )
631 main.log.error( "response: " + str( self.handle.before ) )
632 response = self.handle.before
633 main.log.info( self.name + ": Ping Response: " + response )
634 if re.search( ',\s0\%\spacket\sloss', response ):
635 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700636 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700637 else:
alisone4121a92016-11-22 16:31:36 -0800638 main.log.info(
Hari Krishna012a1c12015-08-25 14:23:58 -0700639 self.name +
640 ": PACKET LOST, HOST IS NOT REACHABLE" )
641 return main.FALSE
642
643 except pexpect.EOF:
644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
646 main.cleanup()
647 main.exit()
648 except Exception:
649 main.log.exception( self.name + ": Uncaught exception!" )
650 main.cleanup()
651 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800652
You Wangdb927a52016-02-26 11:03:28 -0800653 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
654 """
655 Description:
656 Ping a set of destination host from host CLI.
657 Logging into a Mininet host CLI is required before calling this funtion.
658 Params:
659 dstIPList is a list of destination ip addresses
660 Returns:
661 main.TRUE if the destination host is reachable
662 main.FALSE otherwise
663 """
664 isReachable = main.TRUE
665 wait = int( wait )
666 cmd = "ping"
667 if IPv6:
668 cmd = cmd + "6"
669 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
670 try:
671 for dstIP in dstIPList:
672 pingCmd = cmd + " " + dstIP
673 self.handle.sendline( pingCmd )
674 i = self.handle.expect( [ self.hostPrompt,
675 '\*\*\* Unknown command: ' + pingCmd,
676 pexpect.TIMEOUT ],
677 timeout=wait + 1 )
678 if i == 0:
679 response = self.handle.before
680 if not re.search( ',\s0\%\spacket\sloss', response ):
681 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
682 isReachable = main.FALSE
683 elif i == 1:
684 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
685 main.cleanup()
686 main.exit()
687 elif i == 2:
688 main.log.error( self.name + ": timeout when waiting for response" )
689 isReachable = main.FALSE
690 else:
691 main.log.error( self.name + ": unknown response: " + self.handle.before )
692 isReachable = main.FALSE
693 except pexpect.TIMEOUT:
694 main.log.exception( self.name + ": TIMEOUT exception" )
695 isReachable = main.FALSE
696 except pexpect.EOF:
697 main.log.error( self.name + ": EOF exception found" )
698 main.log.error( self.name + ": " + self.handle.before )
699 main.cleanup()
700 main.exit()
701 except Exception:
702 main.log.exception( self.name + ": Uncaught exception!" )
703 main.cleanup()
704 main.exit()
705 return isReachable
706
Jon Hall7eb38402015-01-08 17:19:54 -0800707 def checkIP( self, host ):
708 """
709 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700710 try:
711 if self.handle:
712 try:
713 response = self.execute(
714 cmd=host +
715 " ifconfig",
716 prompt="mininet>",
717 timeout=10 )
718 except pexpect.EOF:
719 main.log.error( self.name + ": EOF exception found" )
720 main.log.error( self.name + ": " + self.handle.before )
721 main.cleanup()
722 main.exit()
adminbae64d82013-08-01 10:50:15 -0700723
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700724 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
725 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
726 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
727 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
728 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
729 "[0-9]|25[0-5]|[0-9]{1,2})"
730 # pattern = "inet addr:10.0.0.6"
731 if re.search( pattern, response ):
732 main.log.info( self.name + ": Host Ip configured properly" )
733 return main.TRUE
734 else:
735 main.log.error( self.name + ": Host IP not found" )
736 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700737 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700738 main.log.error( self.name + ": Connection failed to the host" )
739 except Exception:
740 main.log.exception( self.name + ": Uncaught exception!" )
741 main.cleanup()
742 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800743
Jon Hall7eb38402015-01-08 17:19:54 -0800744 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800745 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700746 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 response = self.execute(
748 cmd="h1 /usr/sbin/sshd -D&",
749 prompt="mininet>",
750 timeout=10 )
751 response = self.execute(
752 cmd="h4 /usr/sbin/sshd -D&",
753 prompt="mininet>",
754 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700755 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800756 vars( self )[ key ] = connectargs[ key ]
757 response = self.execute(
758 cmd="xterm h1 h4 ",
759 prompt="mininet>",
760 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800761 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800762 main.log.error( self.name + ": EOF exception found" )
763 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700764 main.cleanup()
765 main.exit()
adminbae64d82013-08-01 10:50:15 -0700766 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800767 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700768 if self.flag == 0:
769 self.flag = 1
770 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800771 else:
adminbae64d82013-08-01 10:50:15 -0700772 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800773
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700774 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700775 """
776 Moves a host from one switch to another on the fly
777 Note: The intf between host and oldSw when detached
778 using detach(), will still show up in the 'net'
779 cmd, because switch.detach() doesn't affect switch.intfs[]
780 ( which is correct behavior since the interfaces
781 haven't moved ).
782 """
783 if self.handle:
784 try:
785 # Bring link between oldSw-host down
786 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
787 "'," + "'down')"
788 print "cmd1= ", cmd
789 response = self.execute( cmd=cmd,
790 prompt="mininet>",
791 timeout=10 )
792
793 # Determine hostintf and Oldswitchintf
794 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
795 ")[0]"
796 print "cmd2= ", cmd
797 self.handle.sendline( cmd )
798 self.handle.expect( "mininet>" )
799
800 # Determine ip and mac address of the host-oldSw interface
801 cmd = "px ipaddr = hintf.IP()"
802 print "cmd3= ", cmd
803 self.handle.sendline( cmd )
804 self.handle.expect( "mininet>" )
805
806 cmd = "px macaddr = hintf.MAC()"
807 print "cmd3= ", cmd
808 self.handle.sendline( cmd )
809 self.handle.expect( "mininet>" )
810
811 # Detach interface between oldSw-host
812 cmd = "px " + oldSw + ".detach( sintf )"
813 print "cmd4= ", cmd
814 self.handle.sendline( cmd )
815 self.handle.expect( "mininet>" )
816
817 # Add link between host-newSw
818 cmd = "py net.addLink(" + host + "," + newSw + ")"
819 print "cmd5= ", cmd
820 self.handle.sendline( cmd )
821 self.handle.expect( "mininet>" )
822
823 # Determine hostintf and Newswitchintf
824 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
825 ")[0]"
826 print "cmd6= ", cmd
827 self.handle.sendline( cmd )
828 self.handle.expect( "mininet>" )
829
830 # Attach interface between newSw-host
831 cmd = "px " + newSw + ".attach( sintf )"
832 print "cmd3= ", cmd
833 self.handle.sendline( cmd )
834 self.handle.expect( "mininet>" )
835
836 # Set ipaddress of the host-newSw interface
837 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
838 print "cmd7 = ", cmd
839 self.handle.sendline( cmd )
840 self.handle.expect( "mininet>" )
841
842 # Set macaddress of the host-newSw interface
843 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
844 print "cmd8 = ", cmd
845 self.handle.sendline( cmd )
846 self.handle.expect( "mininet>" )
847
848 cmd = "net"
849 print "cmd9 = ", cmd
850 self.handle.sendline( cmd )
851 self.handle.expect( "mininet>" )
852 print "output = ", self.handle.before
853
854 # Determine ipaddress of the host-newSw interface
855 cmd = host + " ifconfig"
856 print "cmd10= ", cmd
857 self.handle.sendline( cmd )
858 self.handle.expect( "mininet>" )
859 print "ifconfig o/p = ", self.handle.before
860
861 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700862
863 except pexpect.TIMEOUT:
864 main.log.error(self.name + ": TIMEOUT exception found")
865 main.log.error(self.name + ": " + self.handle.before)
866 main.cleanup()
867 main.exit()
Jon Hall53c5e662016-04-13 16:06:56 -0700868 except pexpect.EOF:
869 main.log.error( self.name + ": EOF exception found" )
870 main.log.error( self.name + ": " + self.handle.before )
871 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700872 except Exception:
873 main.log.exception( self.name + ": Uncaught exception!" )
874 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700875
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700876 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800877 """
878 Moves a host from one switch to another on the fly
879 Note: The intf between host and oldSw when detached
880 using detach(), will still show up in the 'net'
881 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700882 ( which is correct behavior since the interfaces
883 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800884 """
885 if self.handle:
886 try:
Jon Hall439c8912016-04-15 02:22:03 -0700887 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800888 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700889 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800890 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800891 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800892 response = self.execute( cmd=cmd,
893 prompt="mininet>",
894 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700895
kelvin-onlaba1484582015-02-02 15:46:20 -0800896 # Determine hostintf and Oldswitchintf
897 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800898 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800899 print "cmd2= ", cmd
900 self.handle.sendline( cmd )
901 self.handle.expect( "mininet>" )
902
shahshreya73537862015-02-11 15:15:24 -0800903 # Determine ip and mac address of the host-oldSw interface
Jon Hall439c8912016-04-15 02:22:03 -0700904 cmd = "px ipaddr = " + str(IP)
kelvin-onlaba1484582015-02-02 15:46:20 -0800905 print "cmd3= ", cmd
906 self.handle.sendline( cmd )
907 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800908
909 cmd = "px macaddr = hintf.MAC()"
910 print "cmd3= ", cmd
911 self.handle.sendline( cmd )
912 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700913
kelvin-onlaba1484582015-02-02 15:46:20 -0800914 # Detach interface between oldSw-host
915 cmd = "px " + oldSw + ".detach( sintf )"
916 print "cmd4= ", cmd
917 self.handle.sendline( cmd )
918 self.handle.expect( "mininet>" )
919
920 # Add link between host-newSw
921 cmd = "py net.addLink(" + host + "," + newSw + ")"
922 print "cmd5= ", cmd
923 self.handle.sendline( cmd )
924 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700925
kelvin-onlaba1484582015-02-02 15:46:20 -0800926 # Determine hostintf and Newswitchintf
927 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800928 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800929 print "cmd6= ", cmd
930 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700931 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800932
933 # Attach interface between newSw-host
934 cmd = "px " + newSw + ".attach( sintf )"
Jon Hall439c8912016-04-15 02:22:03 -0700935 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800936 self.handle.sendline( cmd )
937 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800938
939 # Set macaddress of the host-newSw interface
940 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700941 print "cmd7 = ", cmd
942 self.handle.sendline( cmd )
943 self.handle.expect( "mininet>" )
944
945 # Set ipaddress of the host-newSw interface
946 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800947 print "cmd8 = ", cmd
948 self.handle.sendline( cmd )
949 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700950
Jon Hall439c8912016-04-15 02:22:03 -0700951 cmd = host + " ifconfig"
952 print "cmd9 =",cmd
953 response = self.execute( cmd = cmd, prompt="mininet>" ,timeout=10 )
954 print response
955 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700956 ipAddressSearch = re.search( pattern, response )
Jon Hall439c8912016-04-15 02:22:03 -0700957 print ipAddressSearch.group(1)
958 intf= host + "-eth" + str(ipAddressSearch.group(1))
959 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
960 print "cmd10 = ", cmd
961 self.handle.sendline( cmd )
962 self.handle.expect( "mininet>" )
963
kelvin-onlaba1484582015-02-02 15:46:20 -0800964 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700965 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800966 self.handle.sendline( cmd )
967 self.handle.expect( "mininet>" )
968 print "output = ", self.handle.before
969
970 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800971 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700972 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800973 self.handle.sendline( cmd )
974 self.handle.expect( "mininet>" )
975 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700976
kelvin-onlaba1484582015-02-02 15:46:20 -0800977 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700978 except pexpect.TIMEOUT:
979 main.log.error(self.name + ": TIMEOUT exception found")
980 main.log.error(self.name + ": " + self.handle.before)
981 main.cleanup()
982 main.exit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800983 except pexpect.EOF:
984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
986 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700987 except Exception:
988 main.log.exception( self.name + ": Uncaught exception!" )
989 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800990
Jon Hall7eb38402015-01-08 17:19:54 -0800991 def changeIP( self, host, intf, newIP, newNetmask ):
992 """
993 Changes the ip address of a host on the fly
994 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800995 if self.handle:
996 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800997 cmd = host + " ifconfig " + intf + " " + \
998 newIP + " " + 'netmask' + " " + newNetmask
999 self.handle.sendline( cmd )
1000 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001001 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001002 main.log.info( "response = " + response )
1003 main.log.info(
1004 "Ip of host " +
1005 host +
1006 " changed to new IP " +
1007 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001008 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001009 except pexpect.TIMEOUT:
1010 main.log.error(self.name + ": TIMEOUT exception found")
1011 main.log.error(self.name + ": " + self.handle.before)
1012 main.cleanup()
1013 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001014 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001015 main.log.error( self.name + ": EOF exception found" )
1016 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001017 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001018 except Exception:
1019 main.log.exception( self.name + ": Uncaught exception!" )
1020 main.cleanup()
1021 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001022
Jon Hall7eb38402015-01-08 17:19:54 -08001023 def changeDefaultGateway( self, host, newGW ):
1024 """
1025 Changes the default gateway of a host
1026 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001027 if self.handle:
1028 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001029 cmd = host + " route add default gw " + newGW
1030 self.handle.sendline( cmd )
1031 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001032 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001033 main.log.info( "response = " + response )
1034 main.log.info(
1035 "Default gateway of host " +
1036 host +
1037 " changed to " +
1038 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001039 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001040 except pexpect.TIMEOUT:
1041 main.log.error(self.name + ": TIMEOUT exception found")
1042 main.log.error(self.name + ": " + self.handle.before)
1043 main.cleanup()
1044 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001045 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001046 main.log.error( self.name + ": EOF exception found" )
1047 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001048 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001049 except Exception:
1050 main.log.exception( self.name + ": Uncaught exception!" )
1051 main.cleanup()
1052 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001053
Jon Hall7eb38402015-01-08 17:19:54 -08001054 def addStaticMACAddress( self, host, GW, macaddr ):
1055 """
Jon Hallefbd9792015-03-05 16:11:36 -08001056 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001057 if self.handle:
1058 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001059 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1060 cmd = host + " arp -s " + GW + " " + macaddr
1061 self.handle.sendline( cmd )
1062 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001063 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001064 main.log.info( "response = " + response )
1065 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001066 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001067 GW +
1068 " changed to " +
1069 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001070 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001071 except pexpect.TIMEOUT:
1072 main.log.error(self.name + ": TIMEOUT exception found")
1073 main.log.error(self.name + ": " + self.handle.before)
1074 main.cleanup()
1075 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001076 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001077 main.log.error( self.name + ": EOF exception found" )
1078 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001079 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001080 except Exception:
1081 main.log.exception( self.name + ": Uncaught exception!" )
1082 main.cleanup()
1083 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001084
Jon Hall7eb38402015-01-08 17:19:54 -08001085 def verifyStaticGWandMAC( self, host ):
1086 """
1087 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001088 if self.handle:
1089 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001090 # h1 arp -an
1091 cmd = host + " arp -an "
1092 self.handle.sendline( cmd )
1093 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001094 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001095 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001096 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001097 except pexpect.TIMEOUT:
1098 main.log.error(self.name + ": TIMEOUT exception found")
1099 main.log.error(self.name + ": " + self.handle.before)
1100 main.cleanup()
1101 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001102 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001103 main.log.error( self.name + ": EOF exception found" )
1104 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001105 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001106 except Exception:
1107 main.log.exception( self.name + ": Uncaught exception!" )
1108 main.cleanup()
1109 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001110
Jon Hall7eb38402015-01-08 17:19:54 -08001111 def getMacAddress( self, host ):
1112 """
1113 Verifies the host's ip configured or not."""
1114 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001115 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001116 response = self.execute(
1117 cmd=host +
1118 " ifconfig",
1119 prompt="mininet>",
1120 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001121 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001122 main.log.error( self.name + ": EOF exception found" )
1123 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001124 main.cleanup()
1125 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001126 except Exception:
1127 main.log.exception( self.name + ": Uncaught exception!" )
1128 main.cleanup()
1129 main.exit()
adminbae64d82013-08-01 10:50:15 -07001130
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001131 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 macAddressSearch = re.search( pattern, response, re.I )
1133 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001134 main.log.info(
1135 self.name +
1136 ": Mac-Address of Host " +
1137 host +
1138 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 macAddress )
1140 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001141 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001142 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001143
Jon Hall7eb38402015-01-08 17:19:54 -08001144 def getInterfaceMACAddress( self, host, interface ):
1145 """
1146 Return the IP address of the interface on the given host"""
1147 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001148 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001149 response = self.execute( cmd=host + " ifconfig " + interface,
1150 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001151 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001152 main.log.error( self.name + ": EOF exception found" )
1153 main.log.error( self.name + ": " + self.handle.before )
1154 main.cleanup()
1155 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001156 except Exception:
1157 main.log.exception( self.name + ": Uncaught exception!" )
1158 main.cleanup()
1159 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001160
1161 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 macAddressSearch = re.search( pattern, response, re.I )
1163 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001164 main.log.info( "No mac address found in %s" % response )
1165 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001167 main.log.info(
1168 "Mac-Address of " +
1169 host +
1170 ":" +
1171 interface +
1172 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 macAddress )
1174 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001175 else:
1176 main.log.error( "Connection failed to the host" )
1177
sathishmad953462015-12-03 17:42:07 +05301178 def getIPAddress( self, host , proto='IPV4'):
Jon Hall7eb38402015-01-08 17:19:54 -08001179 """
1180 Verifies the host's ip configured or not."""
1181 if self.handle:
1182 try:
1183 response = self.execute(
1184 cmd=host +
1185 " ifconfig",
1186 prompt="mininet>",
1187 timeout=10 )
1188 except pexpect.EOF:
1189 main.log.error( self.name + ": EOF exception found" )
1190 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001191 main.cleanup()
1192 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001193 except Exception:
1194 main.log.exception( self.name + ": Uncaught exception!" )
1195 main.cleanup()
1196 main.exit()
adminbae64d82013-08-01 10:50:15 -07001197
sathishmad953462015-12-03 17:42:07 +05301198 pattern = ''
1199 if proto == 'IPV4':
1200 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1201 else:
Jon Hall439c8912016-04-15 02:22:03 -07001202 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001204 main.log.info(
1205 self.name +
1206 ": IP-Address of Host " +
1207 host +
1208 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 ipAddressSearch.group( 1 ) )
1210 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001211 else:
1212 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001213
Jon Hall7eb38402015-01-08 17:19:54 -08001214 def getSwitchDPID( self, switch ):
1215 """
1216 return the datapath ID of the switch"""
1217 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001218 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001219 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001220 response = self.execute(
1221 cmd=cmd,
1222 prompt="mininet>",
1223 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001224 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001225 main.log.error( self.name + ": EOF exception found" )
1226 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001227 main.cleanup()
1228 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001229 except Exception:
1230 main.log.exception( self.name + ": Uncaught exception!" )
1231 main.cleanup()
1232 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001233 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001234 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001235 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001236 main.log.info(
1237 "Couldn't find DPID for switch %s, found: %s" %
1238 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001239 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001240 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001241 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001242 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001243
Jon Hall7eb38402015-01-08 17:19:54 -08001244 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001245 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001246 self.handle.sendline( "" )
1247 self.expect( "mininet>" )
1248 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001249 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001250 response = self.execute(
1251 cmd=cmd,
1252 prompt="mininet>",
1253 timeout=10 )
1254 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001255 response = self.handle.before
1256 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001257 except pexpect.TIMEOUT:
1258 main.log.error(self.name + ": TIMEOUT exception found")
1259 main.log.error(self.name + ": " + self.handle.before)
1260 main.cleanup()
1261 main.exit()
admin2580a0e2014-07-29 11:24:34 -07001262 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001263 main.log.error( self.name + ": EOF exception found" )
1264 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -07001265 main.cleanup()
1266 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001267 except Exception:
1268 main.log.exception( self.name + ": Uncaught exception!" )
1269 main.cleanup()
1270 main.exit()
admin2580a0e2014-07-29 11:24:34 -07001271
Jon Hall7eb38402015-01-08 17:19:54 -08001272 def getInterfaces( self, node ):
1273 """
1274 return information dict about interfaces connected to the node"""
1275 if self.handle:
1276 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001277 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001278 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001279 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001280 response = self.execute(
1281 cmd=cmd,
1282 prompt="mininet>",
1283 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001284 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001285 main.log.error( self.name + ": EOF exception found" )
1286 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001287 main.cleanup()
1288 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001289 except Exception:
1290 main.log.exception( self.name + ": Uncaught exception!" )
1291 main.cleanup()
1292 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001293 return response
1294 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001295 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001296
Jon Hall7eb38402015-01-08 17:19:54 -08001297 def dump( self ):
1298 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001299 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001300 response = self.execute(
1301 cmd='dump',
1302 prompt='mininet>',
1303 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001304 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001305 main.log.error( self.name + ": EOF exception found" )
1306 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001307 main.cleanup()
1308 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001309 except Exception:
1310 main.log.exception( self.name + ": Uncaught exception!" )
1311 main.cleanup()
1312 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001313 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001314
Jon Hall7eb38402015-01-08 17:19:54 -08001315 def intfs( self ):
1316 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001317 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001318 response = self.execute(
1319 cmd='intfs',
1320 prompt='mininet>',
1321 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001322 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001323 main.log.error( self.name + ": EOF exception found" )
1324 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001325 main.cleanup()
1326 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001327 except Exception:
1328 main.log.exception( self.name + ": Uncaught exception!" )
1329 main.cleanup()
1330 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001331 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001332
Jon Hall7eb38402015-01-08 17:19:54 -08001333 def net( self ):
1334 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001335 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001336 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001337 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001338 main.log.error( self.name + ": EOF exception found" )
1339 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001340 main.cleanup()
1341 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001342 except Exception:
1343 main.log.exception( self.name + ": Uncaught exception!" )
1344 main.cleanup()
1345 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001346 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001347
YPZhang81a7d4e2016-04-18 13:10:17 -07001348 def links( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001349 main.log.info( self.name + ": List network links" )
1350 try:
1351 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001352 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001353 except pexpect.EOF:
1354 main.log.error( self.name + ": EOF exception found" )
1355 main.log.error( self.name + ": " + self.handle.before )
1356 main.cleanup()
1357 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001358 except Exception:
1359 main.log.exception( self.name + ": Uncaught exception!" )
1360 main.cleanup()
1361 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07001362 return response
1363
GlennRC61321f22015-07-16 13:36:54 -07001364 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001365 '''
1366 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001367
kelvin-onlab7cce9382015-07-17 10:21:03 -07001368 @parm:
1369 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1370 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1371 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001372 try:
1373 for host1 in hosts:
1374 for host2 in hosts:
1375 if host1 != host2:
1376 if self.iperftcp(host1, host2, timeout) == main.FALSE:
1377 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
1378 except Exception:
1379 main.log.exception( self.name + ": Uncaught exception!" )
1380 main.cleanup()
1381 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001382
1383 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001384 '''
1385 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1386 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001387
kelvin-onlab7cce9382015-07-17 10:21:03 -07001388 @parm:
1389 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1390 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1391 '''
1392 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1393 try:
1394 # Setup the mininet command
1395 cmd1 = 'iperf ' + host1 + " " + host2
1396 self.handle.sendline( cmd1 )
1397 outcome = self.handle.expect( "mininet>", timeout )
1398 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001399
kelvin-onlab7cce9382015-07-17 10:21:03 -07001400 # checks if there are results in the mininet response
1401 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001402 main.log.report(self.name + ": iperf test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001403 # parse the mn results
1404 response = response.split("\r\n")
1405 response = response[len(response)-2]
1406 response = response.split(": ")
1407 response = response[len(response)-1]
1408 response = response.replace("[", "")
1409 response = response.replace("]", "")
1410 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001411
kelvin-onlab7cce9382015-07-17 10:21:03 -07001412 # this is the bandwith two and from the two hosts
1413 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001414
kelvin-onlab7cce9382015-07-17 10:21:03 -07001415 # there should be two elements in the bandwidth list
1416 # ['host1 to host2', 'host2 to host1"]
1417 if len(bandwidth) == 2:
1418 main.log.report(self.name + ": iperf test successful")
1419 return main.TRUE
1420 else:
1421 main.log.error(self.name + ": invalid iperf results")
1422 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001423 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001424 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001425 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001426 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001427 main.log.error( self.name + ": TIMEOUT exception found" )
1428 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001429 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001430 # NOTE: Send ctrl-c to make sure iperf is done
1431 self.handle.sendline( "\x03" )
1432 self.handle.expect( "Interrupt" )
1433 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001434 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001435 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001436 main.log.error( self.name + ": EOF exception found" )
1437 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001438 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001439 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001440 except Exception:
1441 main.log.exception( self.name + ": Uncaught exception!" )
1442 main.cleanup()
1443 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001444
Jon Hall439c8912016-04-15 02:22:03 -07001445 def iperftcpipv6(self, host1="h1", host2="h2", timeout=50):
1446 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1447 try:
1448 IP1 = self.getIPAddress( host1, proto='IPV6' )
1449 cmd1 = host1 +' iperf -V -sD -B '+ str(IP1)
1450 self.handle.sendline( cmd1 )
1451 outcome1 = self.handle.expect( "mininet>")
1452 cmd2 = host2 +' iperf -V -c '+ str(IP1) +' -t 5'
1453 self.handle.sendline( cmd2 )
1454 outcome2 = self.handle.expect( "mininet>")
1455 response1 = self.handle.before
1456 response2 = self.handle.after
1457 print response1,response2
1458 pattern = "connected with "+ str(IP1)
1459 if pattern in response1:
1460 main.log.report(self.name + ": iperf test completed")
1461 return main.TRUE
1462 else:
1463 main.log.error( self.name + ": iperf test failed" )
1464 return main.FALSE
1465 except pexpect.TIMEOUT:
1466 main.log.error( self.name + ": TIMEOUT exception found" )
1467 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1468 self.handle.sendline( "\x03" )
1469 self.handle.expect( "Interrupt" )
1470 self.handle.expect( "mininet>" )
1471 return main.FALSE
1472 except pexpect.EOF:
1473 main.log.error( self.name + ": EOF exception found" )
1474 main.log.error( self.name + ": " + self.handle.before )
1475 main.cleanup()
1476 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001477 except Exception:
1478 main.log.exception( self.name + ": Uncaught exception!" )
1479 main.cleanup()
1480 main.exit()
Jon Hall439c8912016-04-15 02:22:03 -07001481
GlennRC61321f22015-07-16 13:36:54 -07001482 def iperfudpAll(self, hosts, bandwidth="10M"):
1483 '''
1484 Runs the iperfudp function with a given set of hosts and specified
1485 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001486
GlennRC61321f22015-07-16 13:36:54 -07001487 @param:
1488 bandwidth: the targeted bandwidth, in megabits ('M')
1489 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001490 try:
1491 for host1 in hosts:
1492 for host2 in hosts:
1493 if host1 != host2:
1494 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1495 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1496 except TypeError:
1497 main.log.exception(self.name + ": Object not as expected")
1498 return main.FALSE
1499 except Exception:
1500 main.log.exception( self.name + ": Uncaught exception!" )
1501 main.cleanup()
1502 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001503
1504 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1505
kelvin-onlab7cce9382015-07-17 10:21:03 -07001506 '''
1507 Creates an iperf UDP test with a specific bandwidth.
1508 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001509
kelvin-onlab7cce9382015-07-17 10:21:03 -07001510 @param:
1511 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1512 '''
1513 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1514 try:
1515 # setup the mininet command
1516 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1517 self.handle.sendline(cmd)
1518 self.handle.expect("mininet>")
1519 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001520
kelvin-onlab7cce9382015-07-17 10:21:03 -07001521 # check if there are in results in the mininet response
1522 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001523 main.log.report(self.name + ": iperfudp test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001524 # parse the results
1525 response = response.split("\r\n")
1526 response = response[len(response)-2]
1527 response = response.split(": ")
1528 response = response[len(response)-1]
1529 response = response.replace("[", "")
1530 response = response.replace("]", "")
1531 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001532
kelvin-onlab7cce9382015-07-17 10:21:03 -07001533 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001534
kelvin-onlab7cce9382015-07-17 10:21:03 -07001535 # check to see if there are at least three entries
1536 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1537 if len(mnBandwidth) == 3:
1538 # if one entry is blank then something is wrong
1539 for item in mnBandwidth:
1540 if item == "":
1541 main.log.error(self.name + ": Could not parse iperf output")
1542 main.log.error(self.name + ": invalid iperfudp results")
1543 return main.FALSE
1544 # otherwise results are vaild
1545 main.log.report(self.name + ": iperfudp test successful")
1546 return main.TRUE
1547 else:
1548 main.log.error(self.name + ": invalid iperfudp results")
1549 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001550
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001551 except pexpect.TIMEOUT:
1552 main.log.error(self.name + ": TIMEOUT exception found")
1553 main.log.error(self.name + ": " + self.handle.before)
1554 main.cleanup()
1555 main.exit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001556 except pexpect.EOF:
1557 main.log.error( self.name + ": EOF exception found" )
1558 main.log.error( self.name + ": " + self.handle.before )
1559 main.cleanup()
1560 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001561 except Exception:
1562 main.log.exception( self.name + ": Uncaught exception!" )
1563 main.cleanup()
1564 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001565
Jon Hall7eb38402015-01-08 17:19:54 -08001566 def nodes( self ):
1567 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001568 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001569 response = self.execute(
1570 cmd='nodes',
1571 prompt='mininet>',
1572 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001573 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001576 main.cleanup()
1577 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
1580 main.cleanup()
1581 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001582 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001583
Jon Hall7eb38402015-01-08 17:19:54 -08001584 def pingpair( self ):
1585 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001586 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001587 response = self.execute(
1588 cmd='pingpair',
1589 prompt='mininet>',
1590 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001591 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001592 main.log.error( self.name + ": EOF exception found" )
1593 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001594 main.cleanup()
1595 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001596 except Exception:
1597 main.log.exception( self.name + ": Uncaught exception!" )
1598 main.cleanup()
1599 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001600
Jon Hall7eb38402015-01-08 17:19:54 -08001601 if re.search( ',\s0\%\spacket\sloss', response ):
1602 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001603 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001604 else:
alisone4121a92016-11-22 16:31:36 -08001605 main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001606 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001607
Jon Hall7eb38402015-01-08 17:19:54 -08001608 def link( self, **linkargs ):
1609 """
GlennRCed771242016-01-13 17:02:47 -08001610 Bring link( s ) between two nodes up or down
1611 """
Jon Hall6094a362014-04-11 14:46:56 -07001612 try:
GlennRCed771242016-01-13 17:02:47 -08001613 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1614 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1615 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1616 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1617
1618 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1619 cmd = "link {} {} {}".format( end1, end2, option )
1620 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001621 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001622 response = self.handle.before
1623 main.log.info( response )
1624
1625 return main.TRUE
1626 except pexpect.TIMEOUT:
1627 main.log.exception( self.name + ": Command timed out" )
1628 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001629 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001630 main.log.exception( self.name + ": connection closed." )
Jon Hall6094a362014-04-11 14:46:56 -07001631 main.cleanup()
1632 main.exit()
GlennRCed771242016-01-13 17:02:47 -08001633 except Exception:
1634 main.log.exception( self.name + ": Uncaught exception!" )
1635 main.cleanup()
1636 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001637
pingping-lin8244a3b2015-09-16 13:36:56 -07001638 def switch( self, **switchargs ):
1639 """
1640 start/stop a switch
1641 """
1642 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1643 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1644 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1645 command = "switch " + str( sw ) + " " + str( option )
1646 main.log.info( command )
1647 try:
1648 self.handle.sendline( command )
1649 self.handle.expect( "mininet>" )
1650 except pexpect.TIMEOUT:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001651 main.log.error(self.name + ": TIMEOUT exception found")
1652 main.log.error(self.name + ": " + self.handle.before)
pingping-lin8244a3b2015-09-16 13:36:56 -07001653 main.cleanup()
1654 main.exit()
1655 except pexpect.EOF:
1656 main.log.error( self.name + ": EOF exception found" )
1657 main.log.error( self.name + ": " + self.handle.before )
1658 main.cleanup()
1659 main.exit()
1660 return main.TRUE
1661
pingping-lin5bb663b2015-09-24 11:47:50 -07001662 def node( self, nodeName, commandStr ):
1663 """
1664 Carry out a command line on a given node
1665 @parm:
1666 nodeName: the node name in Mininet testbed
1667 commandStr: the command line will be carried out on the node
1668 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1669 """
1670 command = str( nodeName ) + " " + str( commandStr )
1671 main.log.info( command )
1672
1673 try:
1674 response = self.execute( cmd = command, prompt = "mininet>" )
1675 if re.search( "Unknown command", response ):
1676 main.log.warn( response )
1677 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001678 if re.search( "Permission denied", response ):
1679 main.log.warn( response )
1680 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001681 except pexpect.EOF:
1682 main.log.error( self.name + ": EOF exception found" )
1683 main.log.error( self.name + ": " + self.handle.before )
1684 main.cleanup()
1685 main.exit()
1686 main.log.info( " response is :" )
1687 main.log.info( response )
1688 return response
1689
Jon Hall7eb38402015-01-08 17:19:54 -08001690 def yank( self, **yankargs ):
1691 """
1692 yank a mininet switch interface to a host"""
1693 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001694 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001695 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1696 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1697 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001698 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001699 response = self.execute(
1700 cmd=command,
1701 prompt="mininet>",
1702 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001703 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001704 main.log.error( self.name + ": EOF exception found" )
1705 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001706 main.cleanup()
1707 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001708 except Exception:
1709 main.log.exception( self.name + ": Uncaught exception!" )
1710 main.cleanup()
1711 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001712 return main.TRUE
1713
Jon Hall7eb38402015-01-08 17:19:54 -08001714 def plug( self, **plugargs ):
1715 """
1716 plug the yanked mininet switch interface to a switch"""
1717 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001718 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001719 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1720 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1721 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001722 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001723 response = self.execute(
1724 cmd=command,
1725 prompt="mininet>",
1726 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001727 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001728 main.log.error( self.name + ": EOF exception found" )
1729 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001730 main.cleanup()
1731 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001732 except Exception:
1733 main.log.exception( self.name + ": Uncaught exception!" )
1734 main.cleanup()
1735 main.exit()
adminbae64d82013-08-01 10:50:15 -07001736 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001737
Jon Hall7eb38402015-01-08 17:19:54 -08001738 def dpctl( self, **dpctlargs ):
1739 """
1740 Run dpctl command on all switches."""
1741 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001742 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001743 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1744 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1745 command = "dpctl " + cmd + " " + str( cmdargs )
1746 try:
1747 response = self.execute(
1748 cmd=command,
1749 prompt="mininet>",
1750 timeout=10 )
1751 except pexpect.EOF:
1752 main.log.error( self.name + ": EOF exception found" )
1753 main.log.error( self.name + ": " + self.handle.before )
1754 main.cleanup()
1755 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001756 except Exception:
1757 main.log.exception( self.name + ": Uncaught exception!" )
1758 main.cleanup()
1759 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001760 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001761
kelvin-onlabd3b64892015-01-20 13:26:24 -08001762 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001763 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001764 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001765 try:
1766 fileInput = path + '/lib/Mininet/INSTALL'
1767 version = super( Mininet, self ).getVersion()
1768 pattern = 'Mininet\s\w\.\w\.\w\w*'
1769 for line in open( fileInput, 'r' ).readlines():
1770 result = re.match( pattern, line )
1771 if result:
1772 version = result.group( 0 )
1773 return version
1774 except Exception:
1775 main.log.exception( self.name + ": Uncaught exception!" )
1776 main.cleanup()
1777 main.exit()
adminbae64d82013-08-01 10:50:15 -07001778
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001780 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001781 Parameters:
1782 sw: The name of an OVS switch. Example "s1"
1783 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001784 The output of the command from the mininet cli
1785 or main.FALSE on timeout"""
1786 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001787 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001788 response = self.execute(
1789 cmd=command,
1790 prompt="mininet>",
1791 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001792 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001793 return response
admin2a9548d2014-06-17 14:08:07 -07001794 else:
1795 return main.FALSE
1796 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001797 main.log.error( self.name + ": EOF exception found" )
1798 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001799 main.cleanup()
1800 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001801 except Exception:
1802 main.log.exception( self.name + ": Uncaught exception!" )
1803 main.cleanup()
1804 main.exit()
adminbae64d82013-08-01 10:50:15 -07001805
Charles Chan029be652015-08-24 01:46:10 +08001806 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001807 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001808 Description:
1809 Assign switches to the controllers ( for ovs use only )
1810 Required:
1811 sw - Name of the switch. This can be a list or a string.
1812 ip - Ip addresses of controllers. This can be a list or a string.
1813 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001814 port - ONOS use port 6653, if no list of ports is passed, then
1815 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001816 ptcp - ptcp number, This can be a string or a list that has
1817 the same length as switch. This is optional and not required
1818 when using ovs switches.
1819 NOTE: If switches and ptcp are given in a list type they should have the
1820 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1821 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001822
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001823 Return:
1824 Returns main.TRUE if mininet correctly assigned switches to
1825 controllers, otherwise it will return main.FALSE or an appropriate
1826 exception(s)
1827 """
1828 assignResult = main.TRUE
1829 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001830 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001831 command = "sh ovs-vsctl set-controller "
1832 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001833 try:
1834 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001835 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001836 if isinstance( port, types.StringType ) or \
1837 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001838 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001839 elif isinstance( port, types.ListType ):
1840 main.log.error( self.name + ": Only one controller " +
1841 "assigned and a list of ports has" +
1842 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001843 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001844 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001845 main.log.error( self.name + ": Invalid controller port " +
1846 "number. Please specify correct " +
1847 "controller port" )
1848 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001849
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001850 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001851 if isinstance( port, types.StringType ) or \
1852 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001853 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001854 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1855 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001856 elif isinstance( port, types.ListType ):
1857 if ( len( ip ) != len( port ) ):
1858 main.log.error( self.name + ": Port list = " +
1859 str( len( port ) ) +
1860 "should be the same as controller" +
1861 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001862 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001863 else:
1864 onosIp = ""
1865 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001866 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1867 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001868 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001869 main.log.error( self.name + ": Invalid controller port " +
1870 "number. Please specify correct " +
1871 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001872 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001873 else:
1874 main.log.error( self.name + ": Invalid ip address" )
1875 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001876
1877 if isinstance( sw, types.StringType ):
1878 command += sw + " "
1879 if ptcp:
1880 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001881 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001882 elif isinstance( ptcp, types.ListType ):
1883 main.log.error( self.name + ": Only one switch is " +
1884 "being set and multiple PTCP is " +
1885 "being passed " )
1886 else:
1887 main.log.error( self.name + ": Invalid PTCP" )
1888 ptcp = ""
1889 command += onosIp
1890 commandList.append( command )
1891
1892 elif isinstance( sw, types.ListType ):
1893 if ptcp:
1894 if isinstance( ptcp, types.ListType ):
1895 if len( ptcp ) != len( sw ):
1896 main.log.error( self.name + ": PTCP length = " +
1897 str( len( ptcp ) ) +
1898 " is not the same as switch" +
1899 " length = " +
1900 str( len( sw ) ) )
1901 return main.FALSE
1902 else:
1903 for switch, ptcpNum in zip( sw, ptcp ):
1904 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001905 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001906 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001907 tempCmd += onosIp
1908 commandList.append( tempCmd )
1909 else:
1910 main.log.error( self.name + ": Invalid PTCP" )
1911 return main.FALSE
1912 else:
1913 for switch in sw:
1914 tempCmd = "sh ovs-vsctl set-controller "
1915 tempCmd += switch + " " + onosIp
1916 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001917 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001918 main.log.error( self.name + ": Invalid switch type " )
1919 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001920
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001921 for cmd in commandList:
1922 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001923 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001924 except pexpect.TIMEOUT:
1925 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1926 return main.FALSE
1927 except pexpect.EOF:
1928 main.log.error( self.name + ": EOF exception found" )
1929 main.log.error( self.name + ": " + self.handle.before )
1930 main.cleanup()
1931 main.exit()
1932 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001933 except pexpect.EOF:
1934 main.log.error( self.name + ": EOF exception found" )
1935 main.log.error( self.name + ": " + self.handle.before )
1936 main.cleanup()
1937 main.exit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001938 except Exception:
1939 main.log.exception( self.name + ": Uncaught exception!" )
1940 main.cleanup()
1941 main.exit()
adminbae64d82013-08-01 10:50:15 -07001942
kelvin-onlabd3b64892015-01-20 13:26:24 -08001943 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001944 """
1945 Removes the controller target from sw"""
1946 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001947 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001948 response = self.execute(
1949 cmd=command,
1950 prompt="mininet>",
1951 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001952 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001953 main.log.error( self.name + ": EOF exception found" )
1954 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001955 main.cleanup()
1956 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001957 except Exception:
1958 main.log.exception( self.name + ": Uncaught exception!" )
1959 main.cleanup()
1960 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001961 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001962 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001963
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001965 """
Jon Hallb1290e82014-11-18 16:17:48 -05001966 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001967 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001968 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001969 NOTE: cannot currently specify what type of switch
1970 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001971 sw = name of the new switch as a string
1972 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001973 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001974 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001975 """
1976 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001977 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001978 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001979 response = self.execute(
1980 cmd=command,
1981 prompt="mininet>",
1982 timeout=10 )
1983 if re.search( "already exists!", response ):
1984 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001985 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001986 elif re.search( "Error", response ):
1987 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001988 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001989 elif re.search( "usage:", response ):
1990 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001991 return main.FALSE
1992 else:
1993 return main.TRUE
1994 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001995 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001996 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001997 main.cleanup()
1998 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001999 except Exception:
2000 main.log.exception( self.name + ": Uncaught exception!" )
2001 main.cleanup()
2002 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002003
kelvin-onlabd3b64892015-01-20 13:26:24 -08002004 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002005 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002006 delete a switch from the mininet topology
2007 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002008 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002009 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002010 sw = name of the switch as a string
2011 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002012 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002013 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002014 response = self.execute(
2015 cmd=command,
2016 prompt="mininet>",
2017 timeout=10 )
2018 if re.search( "no switch named", response ):
2019 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002020 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002021 elif re.search( "Error", response ):
2022 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002023 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002024 elif re.search( "usage:", response ):
2025 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002026 return main.FALSE
2027 else:
2028 return main.TRUE
2029 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002030 main.log.error( self.name + ": EOF exception found" )
2031 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002032 main.cleanup()
2033 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002034 except Exception:
2035 main.log.exception( self.name + ": Uncaught exception!" )
2036 main.cleanup()
2037 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002038
You Wangdb8cd0a2016-05-26 15:19:45 -07002039 def getSwitchRandom( self, timeout=60, nonCut=True ):
2040 """
2041 Randomly get a switch from Mininet topology.
2042 If nonCut is True, it gets a list of non-cut switches (the deletion
2043 of a non-cut switch will not increase the number of connected
2044 components of a graph) and randomly returns one of them, otherwise
2045 it just randomly returns one switch from all current switches in
2046 Mininet.
2047 Returns the name of the chosen switch.
2048 """
2049 import random
2050 candidateSwitches = []
2051 try:
2052 if not nonCut:
2053 switches = self.getSwitches( timeout=timeout )
2054 assert len( switches ) != 0
2055 for switchName in switches.keys():
2056 candidateSwitches.append( switchName )
2057 else:
2058 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2059 if graphDict == None:
2060 return None
2061 self.graph.update( graphDict )
2062 candidateSwitches = self.graph.getNonCutVertices()
2063 if candidateSwitches == None:
2064 return None
2065 elif len( candidateSwitches ) == 0:
2066 main.log.info( self.name + ": No candidate switch for deletion" )
2067 return None
2068 else:
2069 switch = random.sample( candidateSwitches, 1 )
2070 return switch[ 0 ]
2071 except KeyError:
2072 main.log.exception( self.name + ": KeyError exception found" )
2073 return None
2074 except AssertionError:
2075 main.log.exception( self.name + ": AssertionError exception found" )
2076 return None
2077 except Exception:
2078 main.log.exception( self.name + ": Uncaught exception" )
2079 return None
2080
2081 def delSwitchRandom( self, timeout=60, nonCut=True ):
2082 """
2083 Randomly delete a switch from Mininet topology.
2084 If nonCut is True, it gets a list of non-cut switches (the deletion
2085 of a non-cut switch will not increase the number of connected
2086 components of a graph) and randomly chooses one for deletion,
2087 otherwise it just randomly delete one switch from all current
2088 switches in Mininet.
2089 Returns the name of the deleted switch
2090 """
2091 try:
2092 switch = self.getSwitchRandom( timeout, nonCut )
2093 if switch == None:
2094 return None
2095 else:
2096 deletionResult = self.delSwitch( switch )
2097 if deletionResult:
2098 return switch
2099 else:
2100 return None
2101 except Exception:
2102 main.log.exception( self.name + ": Uncaught exception" )
2103 return None
2104
kelvin-onlabd3b64892015-01-20 13:26:24 -08002105 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002106 """
2107 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002108 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002109 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002110 NOTE: cannot currently specify what type of link
2111 required params:
2112 node1 = the string node name of the first endpoint of the link
2113 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002114 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002115 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002116 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002117 response = self.execute(
2118 cmd=command,
2119 prompt="mininet>",
2120 timeout=10 )
2121 if re.search( "doesnt exist!", response ):
2122 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002123 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002124 elif re.search( "Error", response ):
2125 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002126 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002127 elif re.search( "usage:", response ):
2128 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002129 return main.FALSE
2130 else:
2131 return main.TRUE
2132 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002135 main.cleanup()
2136 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002137 except Exception:
2138 main.log.exception( self.name + ": Uncaught exception!" )
2139 main.cleanup()
2140 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002141
kelvin-onlabd3b64892015-01-20 13:26:24 -08002142 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002143 """
2144 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002145 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002146 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002147 required params:
2148 node1 = the string node name of the first endpoint of the link
2149 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002150 returns: main.FALSE on an error, else main.TRUE
2151 """
Jon Hallffb386d2014-11-21 13:43:38 -08002152 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002153 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002154 response = self.execute(
2155 cmd=command,
2156 prompt="mininet>",
2157 timeout=10 )
2158 if re.search( "no node named", response ):
2159 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002160 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002161 elif re.search( "Error", response ):
2162 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002163 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002164 elif re.search( "usage:", response ):
2165 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002166 return main.FALSE
2167 else:
2168 return main.TRUE
2169 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002170 main.log.error( self.name + ": EOF exception found" )
2171 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002172 main.cleanup()
2173 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002174 except Exception:
2175 main.log.exception( self.name + ": Uncaught exception!" )
2176 main.cleanup()
2177 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002178
You Wangdb8cd0a2016-05-26 15:19:45 -07002179 def getLinkRandom( self, timeout=60, nonCut=True ):
2180 """
2181 Randomly get a link from Mininet topology.
2182 If nonCut is True, it gets a list of non-cut links (the deletion
2183 of a non-cut link will not increase the number of connected
2184 component of a graph) and randomly returns one of them, otherwise
2185 it just randomly returns one link from all current links in
2186 Mininet.
2187 Returns the link as a list, e.g. [ 's1', 's2' ]
2188 """
2189 import random
2190 candidateLinks = []
2191 try:
2192 if not nonCut:
2193 links = self.getLinks( timeout=timeout )
2194 assert len( links ) != 0
2195 for link in links:
2196 # Exclude host-switch link
2197 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2198 continue
2199 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2200 else:
2201 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2202 if graphDict == None:
2203 return None
2204 self.graph.update( graphDict )
2205 candidateLinks = self.graph.getNonCutEdges()
2206 if candidateLinks == None:
2207 return None
2208 elif len( candidateLinks ) == 0:
2209 main.log.info( self.name + ": No candidate link for deletion" )
2210 return None
2211 else:
2212 link = random.sample( candidateLinks, 1 )
2213 return link[ 0 ]
2214 except KeyError:
2215 main.log.exception( self.name + ": KeyError exception found" )
2216 return None
2217 except AssertionError:
2218 main.log.exception( self.name + ": AssertionError exception found" )
2219 return None
2220 except Exception:
2221 main.log.exception( self.name + ": Uncaught exception" )
2222 return None
2223
2224 def delLinkRandom( self, timeout=60, nonCut=True ):
2225 """
2226 Randomly delete a link from Mininet topology.
2227 If nonCut is True, it gets a list of non-cut links (the deletion
2228 of a non-cut link will not increase the number of connected
2229 component of a graph) and randomly chooses one for deletion,
2230 otherwise it just randomly delete one link from all current links
2231 in Mininet.
2232 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2233 """
2234 try:
2235 link = self.getLinkRandom( timeout, nonCut )
2236 if link == None:
2237 return None
2238 else:
2239 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2240 if deletionResult:
2241 return link
2242 else:
2243 return None
2244 except Exception:
2245 main.log.exception( self.name + ": Uncaught exception" )
2246 return None
2247
kelvin-onlabd3b64892015-01-20 13:26:24 -08002248 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002249 """
Jon Hallb1290e82014-11-18 16:17:48 -05002250 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002251 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002252 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002253 NOTE: cannot currently specify what type of host
2254 required params:
2255 hostname = the string hostname
2256 optional key-value params
2257 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002258 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002259 """
2260 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002261 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002262 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002263 response = self.execute(
2264 cmd=command,
2265 prompt="mininet>",
2266 timeout=10 )
2267 if re.search( "already exists!", response ):
2268 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002269 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002270 elif re.search( "doesnt exists!", response ):
2271 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002272 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002273 elif re.search( "Error", response ):
2274 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002275 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002276 elif re.search( "usage:", response ):
2277 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002278 return main.FALSE
2279 else:
2280 return main.TRUE
2281 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002282 main.log.error( self.name + ": EOF exception found" )
2283 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002284 main.cleanup()
2285 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002286 except Exception:
2287 main.log.exception( self.name + ": Uncaught exception!" )
2288 main.cleanup()
2289 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002290
kelvin-onlabd3b64892015-01-20 13:26:24 -08002291 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002292 """
2293 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002294 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002295 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002296 NOTE: this uses a custom mn function
2297 required params:
2298 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002299 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002300 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002301 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002302 response = self.execute(
2303 cmd=command,
2304 prompt="mininet>",
2305 timeout=10 )
2306 if re.search( "no host named", response ):
2307 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002308 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002309 elif re.search( "Error", response ):
2310 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002311 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002312 elif re.search( "usage:", response ):
2313 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002314 return main.FALSE
2315 else:
2316 return main.TRUE
2317 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002318 main.log.error( self.name + ": EOF exception found" )
2319 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002320 main.cleanup()
2321 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002322 except Exception:
2323 main.log.exception( self.name + ": Uncaught exception!" )
2324 main.cleanup()
2325 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07002326
Jon Hall7eb38402015-01-08 17:19:54 -08002327 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002328 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002329 Called at the end of the test to stop the mininet and
2330 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002331 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002332 try:
2333 self.handle.sendline( '' )
2334 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2335 timeout=2 )
2336 response = main.TRUE
2337 if i == 0:
2338 response = self.stopNet()
2339 elif i == 1:
2340 return main.TRUE
2341 # print "Disconnecting Mininet"
2342 if self.handle:
2343 self.handle.sendline( "exit" )
2344 self.handle.expect( "exit" )
2345 self.handle.expect( "(.*)" )
2346 else:
2347 main.log.error( "Connection failed to the host" )
2348 return response
2349 except pexpect.EOF:
2350 main.log.error( self.name + ": EOF exception found" )
2351 main.log.error( self.name + ": " + self.handle.before )
2352 main.cleanup()
2353 main.exit()
2354 except Exception:
2355 main.log.exception( self.name + ": Uncaught exception!" )
2356 main.cleanup()
2357 main.exit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002358
Jon Halld80cc142015-07-06 13:36:05 -07002359 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002360 """
Jon Hall21270ac2015-02-16 17:59:55 -08002361 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002362 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002363 main.FALSE if the pexpect handle does not exist.
2364
Jon Halld61331b2015-02-17 16:35:47 -08002365 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002366 """
Jon Halld61331b2015-02-17 16:35:47 -08002367 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002368 response = ''
2369 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002370 try:
Jon Halld80cc142015-07-06 13:36:05 -07002371 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002372 i = self.handle.expect( [ 'mininet>',
2373 '\$',
2374 pexpect.EOF,
2375 pexpect.TIMEOUT ],
2376 timeout )
2377 if i == 0:
2378 main.log.info( "Exiting mininet..." )
Jeremyd9e4eb12016-04-13 12:09:06 -07002379 response = self.execute( cmd="exit",
2380 prompt="(.*)",
2381 timeout=120 )
2382 main.log.info( self.name + ": Stopped" )
2383 self.handle.sendline( "sudo mn -c" )
2384 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002385
Jeremyd9e4eb12016-04-13 12:09:06 -07002386 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002387 main.log.info( " Mininet trying to exit while not " +
2388 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002389 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002390 elif i == 2:
2391 main.log.error( "Something went wrong exiting mininet" )
2392 elif i == 3: # timeout
2393 main.log.error( "Something went wrong exiting mininet " +
2394 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002395
Hari Krishnab35c6d02015-03-18 11:13:51 -07002396 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002397 self.handle.sendline( "" )
2398 self.handle.expect( '\$' )
2399 self.handle.sendline(
2400 "sudo kill -9 \`ps -ef | grep \"" +
2401 fileName +
2402 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002403 except pexpect.TIMEOUT:
2404 main.log.error(self.name + ": TIMEOUT exception found")
2405 main.log.error(self.name + ": " + self.handle.before)
2406 main.cleanup()
2407 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002408 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002409 main.log.error( self.name + ": EOF exception found" )
2410 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07002411 main.cleanup()
2412 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002413 except Exception:
2414 main.log.exception( self.name + ": Uncaught exception!" )
2415 main.cleanup()
2416 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08002417 else:
2418 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002419 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002420 return response
2421
YPZhang26a139e2016-04-25 14:01:55 -07002422 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002423 """
2424 Description:
2425 Sends arp message from mininet host for hosts discovery
2426 Required:
2427 host - hosts name
2428 Optional:
2429 ip - ip address that does not exist in the network so there would
2430 be no reply.
2431 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002432 if ethDevice:
2433 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002434 cmd = srcHost + " arping -c1 "
2435 if noResult:
2436 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
2437 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002438 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002439 if output:
2440 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002441 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002442 i = self.handle.expect( [ "mininet>", "arping: " ] )
2443 if i == 0:
2444 return main.TRUE
2445 elif i == 1:
2446 response = self.handle.before + self.handle.after
2447 self.handle.expect( "mininet>" )
2448 response += self.handle.before + self.handle.after
2449 main.log.warn( "Error sending arping, output was: " +
2450 response )
2451 return main.FALSE
2452 except pexpect.TIMEOUT:
2453 main.log.error( self.name + ": TIMEOUT exception found" )
2454 main.log.warn( self.handle.before )
2455 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002456 except pexpect.EOF:
2457 main.log.error( self.name + ": EOF exception found" )
2458 main.log.error( self.name + ": " + self.handle.before )
2459 main.cleanup()
2460 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002461 except Exception:
2462 main.log.exception( self.name + ": Uncaught exception!" )
2463 main.cleanup()
2464 main.exit()
admin07529932013-11-22 14:58:28 -08002465
Jon Hall7eb38402015-01-08 17:19:54 -08002466 def decToHex( self, num ):
2467 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002468
Jon Hall7eb38402015-01-08 17:19:54 -08002469 def getSwitchFlowCount( self, switch ):
2470 """
2471 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002472 if self.handle:
2473 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2474 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002475 response = self.execute(
2476 cmd=cmd,
2477 prompt="mininet>",
2478 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002479 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002480 main.log.error( self.name + ": EOF exception found" )
2481 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002482 main.cleanup()
2483 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002484 except Exception:
2485 main.log.exception( self.name + ": Uncaught exception!" )
2486 main.cleanup()
2487 main.exit()
admin2a9548d2014-06-17 14:08:07 -07002488 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002489 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002490 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002491 main.log.info(
2492 "Couldn't find flows on switch %s, found: %s" %
2493 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002494 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002495 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002496 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002497 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002498
Jon Hall9ed8f372016-02-24 17:34:07 -08002499 def checkFlows( self, sw, dumpFormat=None ):
2500 if dumpFormat:
2501 command = "sh ovs-ofctl -F " + \
2502 dumpFormat + " dump-flows " + str( sw )
2503 else:
2504 command = "sh ovs-ofctl dump-flows " + str( sw )
2505 try:
2506 response = self.execute(
2507 cmd=command,
2508 prompt="mininet>",
2509 timeout=10 )
2510 return response
2511 except pexpect.EOF:
2512 main.log.error( self.name + ": EOF exception found" )
2513 main.log.error( self.name + ": " + self.handle.before )
2514 main.cleanup()
2515 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002516 except Exception:
2517 main.log.exception( self.name + ": Uncaught exception!" )
2518 main.cleanup()
2519 main.exit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002520
GlennRC68467eb2015-11-16 18:01:01 -08002521 def flowTableComp( self, flowTable1, flowTable2 ):
2522 # This function compares the selctors and treatments of each flow
2523 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002524 assert flowTable1, "flowTable1 is empty or None"
2525 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002526 returnValue = main.TRUE
GlennRC68467eb2015-11-16 18:01:01 -08002527 if len(flowTable1) != len(flowTable2):
2528 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002529 returnValue = main.FALSE
GlennRCfa65fce2015-12-16 13:16:08 -08002530 dFields = ["n_bytes", "cookie", "n_packets", "duration"]
2531 for flow1, flow2 in zip(flowTable1, flowTable2):
Jon Hallacd1b182015-12-17 11:43:20 -08002532 for field in dFields:
2533 try:
2534 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002535 except KeyError:
2536 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002537 try:
2538 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002539 except KeyError:
2540 pass
GlennRC68467eb2015-11-16 18:01:01 -08002541 for i in range( len(flowTable1) ):
GlennRC17bbcf52015-12-14 17:31:50 -08002542 if flowTable1[i] not in flowTable2:
2543 main.log.warn( "Flow tables do not match:" )
2544 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[i] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002545 returnValue = main.FALSE
2546 break
2547 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002548 except AssertionError:
2549 main.log.exception( "Nothing to compare" )
2550 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002551 except Exception:
2552 main.log.exception( "Uncaught exception!" )
2553 main.cleanup()
2554 main.exit()
Jon Hall9043c902015-07-30 14:23:44 -07002555
GlennRC528ad292015-11-12 10:38:18 -08002556 def parseFlowTable( self, flowTable, version="", debug=True ):
GlennRC956ea742015-11-05 16:14:15 -08002557 '''
2558 Discription: Parses flows into json format.
2559 NOTE: this can parse any string thats separated with commas
2560 Arguments:
2561 Required:
2562 flows: a list of strings that represnt flows
2563 Optional:
2564 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2565 debug: prints out the final result
2566 returns: A list of flows in json format
2567 '''
GlennRC528ad292015-11-12 10:38:18 -08002568 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002569 try:
2570 for flow in flowTable:
2571 jsonFlow = {}
2572 # split up the fields of the flow
2573 parsedFlow = flow.split(", ")
2574 # get rid of any spaces in front of the field
2575 for i in range( len(parsedFlow) ):
2576 item = parsedFlow[i]
2577 if item[0] == " ":
2578 parsedFlow[i] = item[1:]
2579 # grab the selector and treatment from the parsed flow
2580 # the last element is the selector and the treatment
2581 temp = parsedFlow.pop(-1)
2582 # split up the selector and the treatment
2583 temp = temp.split(" ")
2584 index = 0
2585 # parse the flags
2586 # NOTE: This only parses one flag
2587 flag = {}
2588 if version == "1.3":
2589 flag = {"flag":[temp[index]]}
2590 index += 1
2591 # the first element is the selector and split it up
2592 sel = temp[index]
GlennRC528ad292015-11-12 10:38:18 -08002593 index += 1
You Wang91c37cf2016-05-23 09:39:42 -07002594 sel = sel.split(",")
2595 # the priority is stuck in the selecter so put it back
2596 # in the flow
2597 parsedFlow.append(sel.pop(0))
2598 # parse selector
2599 criteria = []
2600 for item in sel:
2601 # this is the type of the packet e.g. "arp"
2602 if "=" not in item:
2603 criteria.append( {"type":item} )
2604 else:
2605 field = item.split("=")
2606 criteria.append( {field[0]:field[1]} )
2607 selector = {"selector": {"criteria":sorted(criteria)} }
2608 treat = temp[index]
2609 # get rid of the action part e.g. "action=output:2"
2610 # we will add it back later
2611 treat = treat.split("=")
2612 treat.pop(0)
2613 # parse treatment
2614 action = []
2615 for item in treat:
2616 field = item.split(":")
2617 action.append( {field[0]:field[1]} )
2618 # create the treatment field and add the actions
2619 treatment = {"treatment": {"action":sorted(action)} }
2620 # parse the rest of the flow
2621 for item in parsedFlow:
GlennRC528ad292015-11-12 10:38:18 -08002622 field = item.split("=")
You Wang91c37cf2016-05-23 09:39:42 -07002623 jsonFlow.update( {field[0]:field[1]} )
2624 # add the treatment and the selector to the json flow
2625 jsonFlow.update( selector )
2626 jsonFlow.update( treatment )
2627 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002628
You Wang91c37cf2016-05-23 09:39:42 -07002629 if debug: main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format(jsonFlow) )
GlennRC956ea742015-11-05 16:14:15 -08002630
You Wang91c37cf2016-05-23 09:39:42 -07002631 # add the json flow to the json flow table
2632 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002633
You Wang91c37cf2016-05-23 09:39:42 -07002634 return jsonFlowTable
2635
2636 except IndexError:
2637 main.log.exception( self.name + ": IndexError found" )
2638 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002639 except pexpect.EOF:
2640 main.log.error( self.name + ": EOF exception found" )
2641 main.log.error( self.name + ": " + self.handle.before )
2642 main.cleanup()
2643 main.exit()
You Wang91c37cf2016-05-23 09:39:42 -07002644 except Exception:
2645 main.log.exception( self.name + ": Uncaught exception!" )
2646 main.cleanup()
2647 main.exit()
GlennRC528ad292015-11-12 10:38:18 -08002648
Jon Hall0a543792015-12-14 11:00:26 -08002649 def getFlowTable( self, sw, version="", debug=False):
GlennRC956ea742015-11-05 16:14:15 -08002650 '''
2651 Discription: Returns the flow table(s) on a switch or switches in a list.
2652 Each element is a flow.
2653 Arguments:
2654 Required:
2655 sw: The switch name ("s1") to retrive the flow table. Can also be
2656 a list of switches.
2657 Optional:
2658 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2659 debug: prints out the final result
2660 '''
2661 try:
2662 switches = []
2663 if type(sw) is list:
Jon Hallca7ac292015-11-11 09:28:12 -08002664 switches.extend(sw)
GlennRC956ea742015-11-05 16:14:15 -08002665 else: switches.append(sw)
2666
2667 flows = []
2668 for s in switches:
2669 cmd = "sh ovs-ofctl dump-flows " + s
2670
GlennRC528ad292015-11-12 10:38:18 -08002671 if "1.0" == version:
2672 cmd += " -F OpenFlow10-table_id"
2673 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002674 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002675
2676 main.log.info( "Sending: " + cmd )
2677 self.handle.sendline( cmd )
2678 self.handle.expect( "mininet>" )
2679 response = self.handle.before
2680 response = response.split( "\r\n" )
2681 # dump the first two elements and the last
2682 # the first element is the command that was sent
2683 # the second is the table header
2684 # the last element is empty
2685 response = response[2:-1]
2686 flows.extend( response )
2687
2688 if debug: print "Flows:\n{}\n\n".format(flows)
2689
GlennRC528ad292015-11-12 10:38:18 -08002690 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002691
GlennRC956ea742015-11-05 16:14:15 -08002692 except pexpect.EOF:
2693 main.log.exception( self.name + ": connection closed." )
2694 main.cleanup()
2695 main.exit()
2696 except Exception:
2697 main.log.exception( self.name + ": Uncaught exception!" )
2698 main.cleanup()
2699 main.exit()
2700
2701 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
2702 '''
2703 Discription: Checks whether the ID provided matches a flow ID in Mininet
2704 Arguments:
2705 Required:
2706 sw: The switch name ("s1") to retrive the flow table. Can also be
2707 a list of switches.
2708 flowId: the flow ID in hex format. Can also be a list of IDs
2709 Optional:
2710 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2711 debug: prints out the final result
2712 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2713 NOTE: prints out IDs that are not present
2714 '''
2715 try:
2716 main.log.info( "Getting flows from Mininet" )
2717 flows = self.getFlowTable( sw, version, debug )
You Wang083ae982016-05-25 09:31:09 -07002718 if flows == None:
2719 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002720
2721 if debug: print "flow ids:\n{}\n\n".format(flowId)
2722
2723 # Check flowId is a list or a string
2724 if type( flowId ) is str:
2725 result = False
2726 for f in flows:
2727 if flowId in f.get( 'cookie' ):
2728 result = True
2729 break
2730 # flowId is a list
2731 else:
2732 result = True
2733 # Get flow IDs from Mininet
2734 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2735 # Save the IDs that are not in Mininet
2736 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2737
2738 if debug: print "mn flow ids:\n{}\n\n".format(mnFlowIds)
2739
2740 # Print out the IDs that are not in Mininet
2741 if absentIds:
2742 main.log.warn( "Absent ids: {}".format( absentIds ) )
2743 result = False
2744
2745 return main.TRUE if result else main.FALSE
2746
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002747 except pexpect.EOF:
2748 main.log.error( self.name + ": EOF exception found" )
2749 main.log.error( self.name + ": " + self.handle.before )
2750 main.cleanup()
2751 main.exit()
GlennRC956ea742015-11-05 16:14:15 -08002752 except Exception:
2753 main.log.exception( self.name + ": Uncaught exception!" )
2754 main.cleanup()
2755 main.exit()
2756
2757
Charles Chan029be652015-08-24 01:46:10 +08002758 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002759 """
Jon Hallefbd9792015-03-05 16:11:36 -08002760 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002761 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002762 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002763 self.handle.sendline( "" )
2764 self.handle.expect( "mininet>" )
2765 self.handle.sendline(
2766 "sh sudo tcpdump -n -i " +
2767 intf +
2768 " " +
2769 port +
2770 " -w " +
2771 filename.strip() +
2772 " &" )
2773 self.handle.sendline( "" )
2774 i = self.handle.expect( [ 'No\ssuch\device',
2775 'listening\son',
2776 pexpect.TIMEOUT,
2777 "mininet>" ],
2778 timeout=10 )
2779 main.log.warn( self.handle.before + self.handle.after )
2780 self.handle.sendline( "" )
2781 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002782 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002783 main.log.error(
2784 self.name +
2785 ": tcpdump - No such device exists. " +
2786 "tcpdump attempted on: " +
2787 intf )
admin2a9548d2014-06-17 14:08:07 -07002788 return main.FALSE
2789 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002790 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002791 return main.TRUE
2792 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002793 main.log.error(
2794 self.name +
2795 ": tcpdump command timed out! Check interface name," +
2796 " given interface was: " +
2797 intf )
admin2a9548d2014-06-17 14:08:07 -07002798 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002799 elif i == 3:
2800 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002801 return main.TRUE
2802 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002803 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002804 return main.FALSE
2805 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002806 main.log.error( self.name + ": EOF exception found" )
2807 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002808 main.cleanup()
2809 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002810 except Exception:
2811 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07002812 main.cleanup()
2813 main.exit()
2814
kelvin-onlabd3b64892015-01-20 13:26:24 -08002815 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002816 """
2817 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002818 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002819 self.handle.sendline( "sh sudo pkill tcpdump" )
2820 self.handle.expect( "mininet>" )
2821 self.handle.sendline( "" )
2822 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002823 except pexpect.TIMEOUT:
2824 main.log.error(self.name + ": TIMEOUT exception found")
2825 main.log.error(self.name + ": " + self.handle.before)
2826 main.cleanup()
2827 main.exit()
admin2a9548d2014-06-17 14:08:07 -07002828 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002829 main.log.error( self.name + ": EOF exception found" )
2830 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002831 main.cleanup()
2832 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002833 except Exception:
2834 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07002835 main.cleanup()
2836 main.exit()
2837
Jon Halld80cc142015-07-06 13:36:05 -07002838 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002839 """
2840 Read ports from a Mininet switch.
2841
2842 Returns a json structure containing information about the
2843 ports of the given switch.
2844 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002845 try:
2846 response = self.getInterfaces( nodeName )
2847 # TODO: Sanity check on response. log if no such switch exists
2848 ports = []
2849 for line in response.split( "\n" ):
2850 if not line.startswith( "name=" ):
2851 continue
2852 portVars = {}
2853 for var in line.split( "," ):
2854 key, value = var.split( "=" )
2855 portVars[ key ] = value
2856 isUp = portVars.pop( 'enabled', "True" )
2857 isUp = "True" in isUp
2858 if verbose:
2859 main.log.info( "Reading switch port %s(%s)" %
2860 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2861 mac = portVars[ 'mac' ]
2862 if mac == 'None':
2863 mac = None
2864 ips = []
2865 ip = portVars[ 'ip' ]
2866 if ip == 'None':
2867 ip = None
2868 ips.append( ip )
2869 name = portVars[ 'name' ]
2870 if name == 'None':
2871 name = None
2872 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2873 if name == 'lo':
2874 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2875 else:
2876 portNo = re.search( portRe, name ).group( 'port' )
2877 ports.append( { 'of_port': portNo,
2878 'mac': str( mac ).replace( '\'', '' ),
2879 'name': name,
2880 'ips': ips,
2881 'enabled': isUp } )
2882 return ports
2883 except pexpect.EOF:
2884 main.log.error( self.name + ": EOF exception found" )
2885 main.log.error( self.name + ": " + self.handle.before )
2886 main.cleanup()
2887 main.exit()
2888 except Exception:
2889 main.log.exception( self.name + ": Uncaught exception!" )
2890 main.cleanup()
2891 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07002892
You Wangdb8cd0a2016-05-26 15:19:45 -07002893 def getOVSPorts( self, nodeName ):
2894 """
2895 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2896
2897 Returns a list of dictionaries containing information about each
2898 port of the given switch.
2899 """
2900 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2901 try:
2902 response = self.execute(
2903 cmd=command,
2904 prompt="mininet>",
2905 timeout=10 )
2906 ports = []
2907 if response:
2908 for line in response.split( "\n" ):
2909 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2910 # Example port:
2911 # 1(s1-eth1): addr:ae:60:72:77:55:51
2912 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2913 result = re.search( pattern, line )
2914 if result:
2915 index = result.group( 'index' )
2916 name = result.group( 'name' )
2917 # This port number is extracted from port name
2918 port = result.group( 'port' )
2919 mac = result.group( 'mac' )
2920 ports.append( { 'index': index,
2921 'name': name,
2922 'port': port,
2923 'mac': mac } )
2924 return ports
2925 except pexpect.EOF:
2926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
2928 main.cleanup()
2929 main.exit()
2930 except Exception:
2931 main.log.exception( self.name + ": Uncaught exception!" )
2932 main.cleanup()
2933 main.exit()
2934
Jon Halld80cc142015-07-06 13:36:05 -07002935 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002936 """
2937 Read switches from Mininet.
2938
2939 Returns a dictionary whose keys are the switch names and the value is
2940 a dictionary containing information about the switch.
2941 """
Jon Halla22481b2015-07-28 17:46:01 -07002942 # NOTE: To support new Mininet switch classes, just append the new
2943 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002944
Jon Halla22481b2015-07-28 17:46:01 -07002945 # Regex patterns to parse 'dump' output
2946 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002947 # <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 -07002948 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002949 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2950 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2951 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002952 try:
2953 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2954 swRE = r"<(?P<class>" + switchClasses + r")" +\
2955 r"(?P<options>\{.*\})?\s" +\
2956 r"(?P<name>[^:]+)\:\s" +\
2957 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2958 r"\spid=(?P<pid>(\d)+)"
2959 # Update mn port info
2960 self.update()
2961 output = {}
2962 dump = self.dump().split( "\n" )
2963 for line in dump:
2964 result = re.search( swRE, line, re.I )
2965 if result:
2966 name = result.group( 'name' )
2967 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2968 pid = result.group( 'pid' )
2969 swClass = result.group( 'class' )
2970 options = result.group( 'options' )
2971 if verbose:
2972 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2973 ports = self.getPorts( name )
2974 output[ name ] = { "dpid": dpid,
2975 "ports": ports,
2976 "swClass": swClass,
2977 "pid": pid,
2978 "options": options }
2979 return output
2980 except pexpect.EOF:
2981 main.log.error( self.name + ": EOF exception found" )
2982 main.log.error( self.name + ": " + self.handle.before )
2983 main.cleanup()
2984 main.exit()
2985 except Exception:
2986 main.log.exception( self.name + ": Uncaught exception!" )
2987 main.cleanup()
2988 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07002989
Jon Halld80cc142015-07-06 13:36:05 -07002990 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002991 """
2992 Read hosts from Mininet.
2993
2994 Returns a dictionary whose keys are the host names and the value is
2995 a dictionary containing information about the host.
2996 """
2997 # Regex patterns to parse dump output
2998 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002999 # <Host h1: pid=12725>
3000 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3001 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3002 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003003 # NOTE: Does not correctly match hosts with multi-links
3004 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3005 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003006 try:
3007 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
3008 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
3009 # update mn port info
3010 self.update()
3011 # Get mininet dump
3012 dump = self.dump().split( "\n" )
3013 hosts = {}
3014 for line in dump:
3015 if "Host" in line :
3016 result = re.search( hostRE, line )
3017 name = result.group( 'name' )
3018 interfaces = []
3019 response = self.getInterfaces( name )
3020 # Populate interface info
3021 for line in response.split( "\n" ):
3022 if line.startswith( "name=" ):
3023 portVars = {}
3024 for var in line.split( "," ):
3025 key, value = var.split( "=" )
3026 portVars[ key ] = value
3027 isUp = portVars.pop( 'enabled', "True" )
3028 isUp = "True" in isUp
3029 if verbose:
3030 main.log.info( "Reading host port %s(%s)" %
3031 ( portVars[ 'name' ],
3032 portVars[ 'mac' ] ) )
3033 mac = portVars[ 'mac' ]
3034 if mac == 'None':
3035 mac = None
3036 ips = []
3037 ip = portVars[ 'ip' ]
3038 if ip == 'None':
3039 ip = None
3040 ips.append( ip )
3041 intfName = portVars[ 'name' ]
3042 if name == 'None':
3043 name = None
3044 interfaces.append( {
3045 "name": intfName,
3046 "ips": ips,
3047 "mac": str( mac ),
3048 "isUp": isUp } )
3049 hosts[ name ] = { "interfaces": interfaces }
3050 return hosts
3051 except pexpect.EOF:
3052 main.log.error( self.name + ": EOF exception found" )
3053 main.log.error( self.name + ": " + self.handle.before )
3054 main.cleanup()
3055 main.exit()
3056 except Exception:
3057 main.log.exception( self.name + ": Uncaught exception!" )
3058 main.cleanup()
3059 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07003060
YPZhang81a7d4e2016-04-18 13:10:17 -07003061 def getLinks( self, timeout=20 ):
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:
3078 self.update()
3079 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:
3082 # s1-eth3<->s2-eth1 (OK OK)
3083 # s13-eth3<->h27-eth0 (OK OK)
3084 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 )
3103 main.cleanup()
3104 main.exit()
3105 except Exception:
3106 main.log.exception( self.name + ": Uncaught exception!" )
3107 main.cleanup()
3108 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07003109
3110 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003111 """
3112 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003113 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003114
Jon Hallafa8a472015-06-12 14:02:42 -07003115 Dependencies:
3116 1. numpy - "sudo pip install numpy"
3117 """
3118 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003119 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003120 try:
3121 mnDPIDs = []
3122 for swName, switch in switches.iteritems():
3123 mnDPIDs.append( switch[ 'dpid' ].lower() )
3124 mnDPIDs.sort()
3125 if switchesJson == "": # if rest call fails
3126 main.log.error(
3127 self.name +
3128 ".compareSwitches(): Empty JSON object given from ONOS" )
3129 return main.FALSE
3130 onos = switchesJson
3131 onosDPIDs = []
3132 for switch in onos:
3133 if switch[ 'available' ]:
3134 onosDPIDs.append(
3135 switch[ 'id' ].replace(
3136 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003137 '' ).replace(
3138 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003139 '' ).lower() )
3140 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003141
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003142 if mnDPIDs != onosDPIDs:
3143 switchResults = main.FALSE
3144 main.log.error( "Switches in MN but not in ONOS:" )
3145 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3146 main.log.error( str( list1 ) )
3147 main.log.error( "Switches in ONOS but not in MN:" )
3148 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3149 main.log.error( str( list2 ) )
3150 else: # list of dpid's match in onos and mn
3151 switchResults = main.TRUE
3152 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003153
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003154 # FIXME: this does not look for extra ports in ONOS, only checks that
3155 # ONOS has what is in MN
3156 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003157
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003158 # PORTS
3159 for name, mnSwitch in switches.iteritems():
3160 mnPorts = []
3161 onosPorts = []
3162 switchResult = main.TRUE
3163 for port in mnSwitch[ 'ports' ]:
3164 if port[ 'enabled' ]:
3165 mnPorts.append( int( port[ 'of_port' ] ) )
3166 for onosSwitch in portsJson:
3167 if onosSwitch[ 'device' ][ 'available' ]:
3168 if onosSwitch[ 'device' ][ 'id' ].replace(
3169 ':',
3170 '' ).replace(
3171 "of",
3172 '' ) == mnSwitch[ 'dpid' ]:
3173 for port in onosSwitch[ 'ports' ]:
3174 if port[ 'isEnabled' ]:
3175 if port[ 'port' ] == 'local':
3176 # onosPorts.append( 'local' )
3177 onosPorts.append( long( uint64( -2 ) ) )
3178 else:
3179 onosPorts.append( int( port[ 'port' ] ) )
3180 break
3181 mnPorts.sort( key=float )
3182 onosPorts.sort( key=float )
3183
3184 mnPortsLog = mnPorts
3185 onosPortsLog = onosPorts
3186 mnPorts = [ x for x in mnPorts ]
3187 onosPorts = [ x for x in onosPorts ]
3188
3189 # TODO: handle other reserved port numbers besides LOCAL
3190 # NOTE: Reserved ports
3191 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3192 # long( uint64( -2 ) )
3193 for mnPort in mnPortsLog:
3194 if mnPort in onosPorts:
3195 # don't set results to true here as this is just one of
3196 # many checks and it might override a failure
3197 mnPorts.remove( mnPort )
3198 onosPorts.remove( mnPort )
3199
3200 # NOTE: OVS reports this as down since there is no link
3201 # So ignoring these for now
3202 # TODO: Come up with a better way of handling these
3203 if 65534 in mnPorts:
3204 mnPorts.remove( 65534 )
3205 if long( uint64( -2 ) ) in onosPorts:
3206 onosPorts.remove( long( uint64( -2 ) ) )
3207 if len( mnPorts ): # the ports of this switch don't match
3208 switchResult = main.FALSE
3209 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3210 if len( onosPorts ): # the ports of this switch don't match
3211 switchResult = main.FALSE
3212 main.log.warn(
3213 "Ports in ONOS but not MN: " +
3214 str( onosPorts ) )
3215 if switchResult == main.FALSE:
3216 main.log.error(
3217 "The list of ports for switch %s(%s) does not match:" %
3218 ( name, mnSwitch[ 'dpid' ] ) )
3219 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3220 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3221 portsResults = portsResults and switchResult
3222 finalResults = finalResults and portsResults
3223 return finalResults
3224 except pexpect.EOF:
3225 main.log.error( self.name + ": EOF exception found" )
3226 main.log.error( self.name + ": " + self.handle.before )
3227 main.cleanup()
3228 main.exit()
3229 except Exception:
3230 main.log.exception( self.name + ": Uncaught exception!" )
3231 main.cleanup()
3232 main.exit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003233
Jon Hallafa8a472015-06-12 14:02:42 -07003234 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003235 """
3236 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003237 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003238
Jon Hallafa8a472015-06-12 14:02:42 -07003239 """
Jon Hall7eb38402015-01-08 17:19:54 -08003240 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003241 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003242 try:
3243 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003244
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003245 mnLinks = []
3246 for l in links:
3247 try:
3248 node1 = switches[ l[ 'node1' ] ]
3249 node2 = switches[ l[ 'node2' ] ]
3250 enabled = True
3251 for port in node1[ 'ports' ]:
3252 if port[ 'of_port' ] == l[ 'port1' ]:
3253 enabled = enabled and port[ 'enabled' ]
3254 for port in node2[ 'ports' ]:
3255 if port[ 'of_port' ] == l[ 'port2' ]:
3256 enabled = enabled and port[ 'enabled' ]
3257 if enabled:
3258 mnLinks.append( l )
3259 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003260 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003261 if 2 * len( mnLinks ) == len( onos ):
3262 linkResults = main.TRUE
3263 else:
3264 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003265 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003266 "Mininet has " + str( len( mnLinks ) ) +
3267 " bidirectional links and ONOS has " +
3268 str( len( onos ) ) + " unidirectional links" )
3269
3270 # iterate through MN links and check if an ONOS link exists in
3271 # both directions
3272 for link in mnLinks:
3273 # TODO: Find a more efficient search method
3274 node1 = None
3275 port1 = None
3276 node2 = None
3277 port2 = None
3278 firstDir = main.FALSE
3279 secondDir = main.FALSE
3280 for swName, switch in switches.iteritems():
3281 if swName == link[ 'node1' ]:
3282 node1 = switch[ 'dpid' ]
3283 for port in switch[ 'ports' ]:
3284 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3285 port1 = port[ 'of_port' ]
3286 if node1 is not None and node2 is not None:
3287 break
3288 if swName == link[ 'node2' ]:
3289 node2 = switch[ 'dpid' ]
3290 for port in switch[ 'ports' ]:
3291 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3292 port2 = port[ 'of_port' ]
3293 if node1 is not None and node2 is not None:
3294 break
3295
3296 for onosLink in onos:
3297 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3298 ":", '' ).replace( "of", '' )
3299 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3300 ":", '' ).replace( "of", '' )
3301 onosPort1 = onosLink[ 'src' ][ 'port' ]
3302 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3303
3304 # check onos link from node1 to node2
3305 if str( onosNode1 ) == str( node1 ) and str(
3306 onosNode2 ) == str( node2 ):
3307 if int( onosPort1 ) == int( port1 ) and int(
3308 onosPort2 ) == int( port2 ):
3309 firstDir = main.TRUE
3310 else:
3311 main.log.warn(
3312 'The port numbers do not match for ' +
3313 str( link ) +
3314 ' between ONOS and MN. When checking ONOS for ' +
3315 'link %s/%s -> %s/%s' %
3316 ( node1, port1, node2, port2 ) +
3317 ' ONOS has the values %s/%s -> %s/%s' %
3318 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3319
3320 # check onos link from node2 to node1
3321 elif ( str( onosNode1 ) == str( node2 ) and
3322 str( onosNode2 ) == str( node1 ) ):
3323 if ( int( onosPort1 ) == int( port2 )
3324 and int( onosPort2 ) == int( port1 ) ):
3325 secondDir = main.TRUE
3326 else:
3327 main.log.warn(
3328 'The port numbers do not match for ' +
3329 str( link ) +
3330 ' between ONOS and MN. When checking ONOS for ' +
3331 'link %s/%s -> %s/%s' %
3332 ( node1, port1, node2, port2 ) +
3333 ' ONOS has the values %s/%s -> %s/%s' %
3334 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3335 else: # this is not the link you're looking for
3336 pass
3337 if not firstDir:
3338 main.log.error(
3339 'ONOS does not have the link %s/%s -> %s/%s' %
3340 ( node1, port1, node2, port2 ) )
3341 if not secondDir:
3342 main.log.error(
3343 'ONOS does not have the link %s/%s -> %s/%s' %
3344 ( node2, port2, node1, port1 ) )
3345 linkResults = linkResults and firstDir and secondDir
3346 return linkResults
3347 except pexpect.EOF:
3348 main.log.error( self.name + ": EOF exception found" )
3349 main.log.error( self.name + ": " + self.handle.before )
3350 main.cleanup()
3351 main.exit()
3352 except Exception:
3353 main.log.exception( self.name + ": Uncaught exception!" )
3354 main.cleanup()
3355 main.exit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003356
Jon Hallafa8a472015-06-12 14:02:42 -07003357 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003358 """
Jon Hallafa8a472015-06-12 14:02:42 -07003359 Compare mn and onos Hosts.
3360 Since Mininet hosts are quiet, ONOS will only know of them when they
3361 speak. For this reason, we will only check that the hosts in ONOS
3362 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003363
Jon Hallafa8a472015-06-12 14:02:42 -07003364 Arguments:
3365 hostsJson: parsed json object from the onos hosts api
3366 Returns:
3367 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003368 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003369 try:
3370 hostResults = main.TRUE
3371 for onosHost in hostsJson:
3372 onosMAC = onosHost[ 'mac' ].lower()
3373 match = False
3374 for mnHost, info in hosts.iteritems():
3375 for mnIntf in info[ 'interfaces' ]:
3376 if onosMAC == mnIntf[ 'mac' ].lower():
3377 match = True
3378 for ip in mnIntf[ 'ips' ]:
3379 if ip in onosHost[ 'ipAddresses' ]:
3380 pass # all is well
3381 else:
3382 # misssing ip
3383 main.log.error( "ONOS host " +
3384 onosHost[ 'id' ] +
3385 " has a different IP(" +
3386 str( onosHost[ 'ipAddresses' ] ) +
3387 ") than the Mininet host(" +
3388 str( ip ) +
3389 ")." )
3390 output = json.dumps(
3391 onosHost,
3392 sort_keys=True,
3393 indent=4,
3394 separators=( ',', ': ' ) )
3395 main.log.info( output )
3396 hostResults = main.FALSE
3397 if not match:
3398 hostResults = main.FALSE
3399 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3400 "corresponding Mininet host." )
3401 output = json.dumps( onosHost,
3402 sort_keys=True,
3403 indent=4,
3404 separators=( ',', ': ' ) )
3405 main.log.info( output )
3406 return hostResults
3407 except pexpect.EOF:
3408 main.log.error(self.name + ": EOF exception found")
3409 main.log.error(self.name + ": " + self.handle.before)
3410 main.cleanup()
3411 main.exit()
3412 except Exception:
3413 main.log.exception(self.name + ": Uncaught exception!")
3414 main.cleanup()
3415 main.exit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003416
Jon Hallafa8a472015-06-12 14:02:42 -07003417 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003418 """
3419 Returns a list of all hosts
3420 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003421 try:
3422 self.handle.sendline( "" )
3423 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003424
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003425 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3426 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003427
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003428 handlePy = self.handle.before
3429 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3430 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003431
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003432 self.handle.sendline( "" )
3433 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003434
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003435 hostStr = handlePy.replace( "]", "" )
3436 hostStr = hostStr.replace( "'", "" )
3437 hostStr = hostStr.replace( "[", "" )
3438 hostStr = hostStr.replace( " ", "" )
3439 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003440
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003441 return hostList
3442 except pexpect.TIMEOUT:
3443 main.log.error(self.name + ": TIMEOUT exception found")
3444 main.log.error(self.name + ": " + self.handle.before)
3445 main.cleanup()
3446 main.exit()
3447 except pexpect.EOF:
3448 main.log.error( self.name + ": EOF exception found" )
3449 main.log.error( self.name + ": " + self.handle.before )
3450 main.cleanup()
3451 main.exit()
3452 except Exception:
3453 main.log.exception( self.name + ": Uncaught exception!" )
3454 main.cleanup()
3455 main.exit()
adminbae64d82013-08-01 10:50:15 -07003456
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003457 def getSwitch( self ):
3458 """
3459 Returns a list of all switches
3460 Again, don't ask question just use it...
3461 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003462 try:
3463 # get host list...
3464 hostList = self.getHosts()
3465 # Make host set
3466 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003467
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003468 # Getting all the nodes in mininet
3469 self.handle.sendline( "" )
3470 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003471
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003472 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3473 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003474
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003475 handlePy = self.handle.before
3476 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3477 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003478
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003479 self.handle.sendline( "" )
3480 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003481
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003482 nodesStr = handlePy.replace( "]", "" )
3483 nodesStr = nodesStr.replace( "'", "" )
3484 nodesStr = nodesStr.replace( "[", "" )
3485 nodesStr = nodesStr.replace( " ", "" )
3486 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003487
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003488 nodesSet = set( nodesList )
3489 # discarding default controller(s) node
3490 nodesSet.discard( 'c0' )
3491 nodesSet.discard( 'c1' )
3492 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003493
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003494 switchSet = nodesSet - hostSet
3495 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003496
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003497 return switchList
3498 except pexpect.TIMEOUT:
3499 main.log.error(self.name + ": TIMEOUT exception found")
3500 main.log.error(self.name + ": " + self.handle.before)
3501 main.cleanup()
3502 main.exit()
3503 except pexpect.EOF:
3504 main.log.error( self.name + ": EOF exception found" )
3505 main.log.error( self.name + ": " + self.handle.before )
3506 main.cleanup()
3507 main.exit()
3508 except Exception:
3509 main.log.exception( self.name + ": Uncaught exception!" )
3510 main.cleanup()
3511 main.exit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003512
You Wangdb8cd0a2016-05-26 15:19:45 -07003513 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3514 """
3515 Return a dictionary which describes the latest Mininet topology data as a
3516 graph.
3517 An example of the dictionary:
3518 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3519 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3520 Each vertex should at least have an 'edges' attribute which describes the
3521 adjacency information. The value of 'edges' attribute is also represented by
3522 a dictionary, which maps each edge (identified by the neighbor vertex) to a
3523 list of attributes.
3524 An example of the edges dictionary:
3525 'edges': { vertex2: { 'port': ..., 'weight': ... },
3526 vertex3: { 'port': ..., 'weight': ... } }
3527 If useId == True, dpid/mac will be used instead of names to identify
3528 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3529 topology.
3530 If includeHost == True, all hosts (and host-switch links) will be included
3531 in topology data.
3532 Note that link or switch that are brought down by 'link x x down' or 'switch
3533 x down' commands still show in the output of Mininet CLI commands such as
3534 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3535 recommended to use delLink() or delSwitch functions to simulate link/switch
3536 down, and addLink() or addSwitch to add them back.
3537 """
3538 graphDict = {}
3539 try:
3540 links = self.getLinks( timeout=timeout )
3541 portDict = {}
3542 if useId:
3543 switches = self.getSwitches()
3544 if includeHost:
3545 hosts = self.getHosts()
3546 for link in links:
3547 # FIXME: support 'includeHost' argument
3548 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3549 continue
3550 nodeName1 = link[ 'node1' ]
3551 nodeName2 = link[ 'node2' ]
3552 port1 = link[ 'port1' ]
3553 port2 = link[ 'port2' ]
3554 # Loop for two nodes
3555 for i in range( 2 ):
3556 # Get port index from OVS
3557 # The index extracted from port name may be inconsistent with ONOS
3558 portIndex = -1
3559 if not nodeName1 in portDict.keys():
3560 portList = self.getOVSPorts( nodeName1 )
3561 if len( portList ) == 0:
3562 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3563 return None
3564 portDict[ nodeName1 ] = portList
3565 for port in portDict[ nodeName1 ]:
3566 if port[ 'port' ] == port1:
3567 portIndex = port[ 'index' ]
3568 break
3569 if portIndex == -1:
3570 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3571 return None
3572 if useId:
3573 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3574 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3575 else:
3576 node1 = nodeName1
3577 node2 = nodeName2
3578 if not node1 in graphDict.keys():
3579 if useId:
3580 graphDict[ node1 ] = { 'edges':{},
3581 'dpid':switches[ nodeName1 ][ 'dpid' ],
3582 'name':nodeName1,
3583 'ports':switches[ nodeName1 ][ 'ports' ],
3584 'swClass':switches[ nodeName1 ][ 'swClass' ],
3585 'pid':switches[ nodeName1 ][ 'pid' ],
3586 'options':switches[ nodeName1 ][ 'options' ] }
3587 else:
3588 graphDict[ node1 ] = { 'edges':{} }
3589 else:
3590 # Assert node2 is not connected to any current links of node1
3591 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
3592 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port':portIndex }
3593 # Swap two nodes/ports
3594 nodeName1, nodeName2 = nodeName2, nodeName1
3595 port1, port2 = port2, port1
3596 return graphDict
3597 except KeyError:
3598 main.log.exception( self.name + ": KeyError exception found" )
3599 return None
3600 except AssertionError:
3601 main.log.exception( self.name + ": AssertionError exception found" )
3602 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003603 except pexpect.EOF:
3604 main.log.error( self.name + ": EOF exception found" )
3605 main.log.error( self.name + ": " + self.handle.before )
3606 main.cleanup()
3607 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003608 except Exception:
3609 main.log.exception( self.name + ": Uncaught exception" )
3610 return None
3611
Jon Hall7eb38402015-01-08 17:19:54 -08003612 def update( self ):
3613 """
3614 updates the port address and status information for
3615 each port in mn"""
3616 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003617 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003618 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003619 self.handle.sendline( "" )
3620 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003621
Jon Hall7eb38402015-01-08 17:19:54 -08003622 self.handle.sendline( "update" )
3623 self.handle.expect( "update" )
3624 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003625
Jon Hall7eb38402015-01-08 17:19:54 -08003626 self.handle.sendline( "" )
3627 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003628
Jon Hallb1290e82014-11-18 16:17:48 -05003629 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003630 except pexpect.TIMEOUT:
3631 main.log.error(self.name + ": TIMEOUT exception found")
3632 main.log.error(self.name + ": " + self.handle.before)
3633 main.cleanup()
3634 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05003635 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003636 main.log.error( self.name + ": EOF exception found" )
3637 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05003638 main.cleanup()
3639 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003640 except Exception:
3641 main.log.exception( self.name + ": Uncaught exception!" )
3642 main.cleanup()
3643 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05003644
Jon Halld80cc142015-07-06 13:36:05 -07003645 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003646 """
3647 Add vlan tag to a host.
3648 Dependencies:
3649 This class depends on the "vlan" package
3650 $ sudo apt-get install vlan
3651 Configuration:
3652 Load the 8021q module into the kernel
3653 $sudo modprobe 8021q
3654
3655 To make this setup permanent:
3656 $ sudo su -c 'echo "8021q" >> /etc/modules'
3657 """
3658 if self.handle:
3659 try:
Jon Halld80cc142015-07-06 13:36:05 -07003660 # get the ip address of the host
3661 main.log.info( "Get the ip address of the host" )
3662 ipaddr = self.getIPAddress( host )
3663 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003664
Jon Halld80cc142015-07-06 13:36:05 -07003665 # remove IP from interface intf
3666 # Ex: h1 ifconfig h1-eth0 inet 0
3667 main.log.info( "Remove IP from interface " )
3668 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3669 self.handle.sendline( cmd2 )
3670 self.handle.expect( "mininet>" )
3671 response = self.handle.before
3672 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003673
Jon Halld80cc142015-07-06 13:36:05 -07003674 # create VLAN interface
3675 # Ex: h1 vconfig add h1-eth0 100
3676 main.log.info( "Create Vlan" )
3677 cmd3 = host + " vconfig add " + intf + " " + vlan
3678 self.handle.sendline( cmd3 )
3679 self.handle.expect( "mininet>" )
3680 response = self.handle.before
3681 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003682
Jon Halld80cc142015-07-06 13:36:05 -07003683 # assign the host's IP to the VLAN interface
3684 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3685 main.log.info( "Assign the host IP to the vlan interface" )
3686 vintf = intf + "." + vlan
3687 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3688 self.handle.sendline( cmd4 )
3689 self.handle.expect( "mininet>" )
3690 response = self.handle.before
3691 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003692
3693 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003694 except pexpect.TIMEOUT:
3695 main.log.error(self.name + ": TIMEOUT exception found")
3696 main.log.error(self.name + ": " + self.handle.before)
3697 main.cleanup()
3698 main.exit()
kaouthera3f13ca22015-05-05 15:01:41 -07003699 except pexpect.EOF:
3700 main.log.error( self.name + ": EOF exception found" )
3701 main.log.error( self.name + ": " + self.handle.before )
3702 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003703 except Exception:
3704 main.log.exception( self.name + ": Uncaught exception!" )
3705 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003706
Jon Hall892818c2015-10-20 17:58:34 -07003707 def createHostComponent( self, name ):
3708 """
3709 Creates a new mininet cli component with the same parameters as self.
3710 This new component is intended to be used to login to the hosts created
3711 by mininet.
3712
3713 Arguments:
3714 name - The string of the name of this component. The new component
3715 will be assigned to main.<name> .
3716 In addition, main.<name>.name = str( name )
3717 """
3718 try:
3719 # look to see if this component already exists
3720 getattr( main, name )
3721 except AttributeError:
3722 # namespace is clear, creating component
3723 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
3724 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
3725 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003726 except pexpect.EOF:
3727 main.log.error( self.name + ": EOF exception found" )
3728 main.log.error( self.name + ": " + self.handle.before )
3729 main.cleanup()
3730 main.exit()
Jon Hall892818c2015-10-20 17:58:34 -07003731 except Exception:
3732 main.log.exception( self.name + ": Uncaught exception!" )
3733 main.cleanup()
3734 main.exit()
3735 else:
3736 # namespace is not clear!
3737 main.log.error( name + " component already exists!" )
3738 # FIXME: Should we exit here?
3739 main.cleanup()
3740 main.exit()
3741
3742 def removeHostComponent( self, name ):
3743 """
3744 Remove host component
3745 Arguments:
3746 name - The string of the name of the component to delete.
3747 """
3748 try:
3749 # Get host component
3750 component = getattr( main, name )
3751 except AttributeError:
3752 main.log.error( "Component " + name + " does not exist." )
3753 return
3754 try:
3755 # Disconnect from component
3756 component.disconnect()
3757 # Delete component
3758 delattr( main, name )
3759 # Delete component from ComponentDictionary
3760 del( main.componentDictionary[name] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003761 except pexpect.EOF:
3762 main.log.error( self.name + ": EOF exception found" )
3763 main.log.error( self.name + ": " + self.handle.before )
3764 main.cleanup()
3765 main.exit()
Jon Hall892818c2015-10-20 17:58:34 -07003766 except Exception:
3767 main.log.exception( self.name + ": Uncaught exception!" )
3768 main.cleanup()
3769 main.exit()
3770
3771 def startHostCli( self, host=None ):
3772 """
3773 Use the mininet m utility to connect to the host's cli
3774 """
3775 # These are fields that can be used by scapy packets. Initialized to None
3776 self.hostIp = None
3777 self.hostMac = None
3778 try:
3779 if not host:
3780 host = self.name
3781 self.handle.sendline( self.home + "/util/m " + host )
3782 self.handle.expect( self.hostPrompt )
3783 return main.TRUE
3784 except pexpect.TIMEOUT:
3785 main.log.exception( self.name + ": Command timed out" )
3786 return main.FALSE
3787 except pexpect.EOF:
3788 main.log.exception( self.name + ": connection closed." )
3789 main.cleanup()
3790 main.exit()
3791 except Exception:
3792 main.log.exception( self.name + ": Uncaught exception!" )
3793 main.cleanup()
3794 main.exit()
3795
YPZhang801d46d2016-08-08 13:26:28 -07003796 def changeInterfaceStatus( self, devicename, intf, status ):
3797 '''
3798
3799 Args:
3800 devicename: switch name
3801 intf: port name on switch
3802 status: up or down
3803
3804 Returns: boolean to show success change status
3805
3806 '''
3807 if status == "down" or status == "up":
3808 try:
3809 cmd = devicename + " ifconfig " + intf + " " + status
3810 self.handle.sendline( cmd )
3811 self.handle.expect("mininet>")
3812 return main.TRUE
3813 except pexpect.TIMEOUT:
3814 main.log.exception(self.name + ": Command timed out")
3815 return main.FALSE
3816 except pexpect.EOF:
3817 main.log.exception(self.name + ": connection closed.")
3818 main.cleanup()
3819 main.exit()
3820 except TypeError:
3821 main.log.exception(self.name + ": TypeError")
3822 main.cleanup()
3823 main.exit()
3824 except Exception:
3825 main.log.exception(self.name + ": Uncaught exception!")
3826 main.cleanup()
3827 main.exit()
3828 else:
3829 main.log.warn("Interface status should be up or down!")
3830 return main.FALSE
3831
3832
Jon Hall892818c2015-10-20 17:58:34 -07003833
adminbae64d82013-08-01 10:50:15 -07003834if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003835 sys.modules[ __name__ ] = MininetCliDriver()