blob: ac3a9a2189ae9f8899f141bf345ef6ec9cab2064 [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:
590 main.log.error(
591 self.name +
592 ": PACKET LOST, HOST IS NOT REACHABLE" )
593 return main.FALSE
594
Jon Hallfbc828e2015-01-06 17:30:19 -0800595 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800596 main.log.error( self.name + ": EOF exception found" )
597 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700598 main.cleanup()
599 main.exit()
Hari Krishna012a1c12015-08-25 14:23:58 -0700600 except Exception:
601 main.log.exception( self.name + ": Uncaught exception!" )
602 main.cleanup()
603 main.exit()
604
605 def ping6pair( self, **pingParams ):
606 """
GlennRC2cf7d952015-09-11 16:32:13 -0700607 IPv6 Ping between a pair of mininet hosts
Jon Hall3b489db2015-10-05 14:38:37 -0700608 Currently the only supported Params are: SRC, TARGET, and WAIT
Hari Krishna012a1c12015-08-25 14:23:58 -0700609 FLOWLABEL and -I (src interface) will be added later after running some tests.
610 Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
611 """
Jon Hall3b489db2015-10-05 14:38:37 -0700612 args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
613 wait = args['WAIT']
614 wait = int( wait if wait else 1 )
Subhash Kumar Singhbcc1c792015-11-07 04:52:11 +0530615 command = args[ "SRC" ] + " ping6 " + \
Jon Hall3b489db2015-10-05 14:38:37 -0700616 args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
Hari Krishna012a1c12015-08-25 14:23:58 -0700617 try:
618 main.log.info( "Sending: " + command )
619 self.handle.sendline( command )
Jon Hall3b489db2015-10-05 14:38:37 -0700620 i = self.handle.expect( [ command, pexpect.TIMEOUT ],
621 timeout=wait + 1 )
Hari Krishna012a1c12015-08-25 14:23:58 -0700622 if i == 1:
623 main.log.error(
624 self.name +
625 ": timeout when waiting for response from mininet" )
626 main.log.error( "response: " + str( self.handle.before ) )
627 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
628 if i == 1:
629 main.log.error(
630 self.name +
631 ": timeout when waiting for response from mininet" )
632 main.log.error( "response: " + str( self.handle.before ) )
633 response = self.handle.before
634 main.log.info( self.name + ": Ping Response: " + response )
635 if re.search( ',\s0\%\spacket\sloss', response ):
636 main.log.info( self.name + ": no packets lost, host is reachable" )
GlennRC2cf7d952015-09-11 16:32:13 -0700637 return main.TRUE
Hari Krishna012a1c12015-08-25 14:23:58 -0700638 else:
639 main.log.error(
640 self.name +
641 ": PACKET LOST, HOST IS NOT REACHABLE" )
642 return main.FALSE
643
644 except pexpect.EOF:
645 main.log.error( self.name + ": EOF exception found" )
646 main.log.error( self.name + ": " + self.handle.before )
647 main.cleanup()
648 main.exit()
649 except Exception:
650 main.log.exception( self.name + ": Uncaught exception!" )
651 main.cleanup()
652 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800653
You Wangdb927a52016-02-26 11:03:28 -0800654 def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
655 """
656 Description:
657 Ping a set of destination host from host CLI.
658 Logging into a Mininet host CLI is required before calling this funtion.
659 Params:
660 dstIPList is a list of destination ip addresses
661 Returns:
662 main.TRUE if the destination host is reachable
663 main.FALSE otherwise
664 """
665 isReachable = main.TRUE
666 wait = int( wait )
667 cmd = "ping"
668 if IPv6:
669 cmd = cmd + "6"
670 cmd = cmd + " -c 1 -i 1 -W " + str( wait )
671 try:
672 for dstIP in dstIPList:
673 pingCmd = cmd + " " + dstIP
674 self.handle.sendline( pingCmd )
675 i = self.handle.expect( [ self.hostPrompt,
676 '\*\*\* Unknown command: ' + pingCmd,
677 pexpect.TIMEOUT ],
678 timeout=wait + 1 )
679 if i == 0:
680 response = self.handle.before
681 if not re.search( ',\s0\%\spacket\sloss', response ):
682 main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
683 isReachable = main.FALSE
684 elif i == 1:
685 main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
686 main.cleanup()
687 main.exit()
688 elif i == 2:
689 main.log.error( self.name + ": timeout when waiting for response" )
690 isReachable = main.FALSE
691 else:
692 main.log.error( self.name + ": unknown response: " + self.handle.before )
693 isReachable = main.FALSE
694 except pexpect.TIMEOUT:
695 main.log.exception( self.name + ": TIMEOUT exception" )
696 isReachable = main.FALSE
697 except pexpect.EOF:
698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
700 main.cleanup()
701 main.exit()
702 except Exception:
703 main.log.exception( self.name + ": Uncaught exception!" )
704 main.cleanup()
705 main.exit()
706 return isReachable
707
Jon Hall7eb38402015-01-08 17:19:54 -0800708 def checkIP( self, host ):
709 """
710 Verifies the host's ip configured or not."""
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700711 try:
712 if self.handle:
713 try:
714 response = self.execute(
715 cmd=host +
716 " ifconfig",
717 prompt="mininet>",
718 timeout=10 )
719 except pexpect.EOF:
720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
722 main.cleanup()
723 main.exit()
adminbae64d82013-08-01 10:50:15 -0700724
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700725 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
726 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
727 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
728 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
729 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
730 "[0-9]|25[0-5]|[0-9]{1,2})"
731 # pattern = "inet addr:10.0.0.6"
732 if re.search( pattern, response ):
733 main.log.info( self.name + ": Host Ip configured properly" )
734 return main.TRUE
735 else:
736 main.log.error( self.name + ": Host IP not found" )
737 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700738 else:
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700739 main.log.error( self.name + ": Connection failed to the host" )
740 except Exception:
741 main.log.exception( self.name + ": Uncaught exception!" )
742 main.cleanup()
743 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -0800744
Jon Hall7eb38402015-01-08 17:19:54 -0800745 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800746 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700747 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 response = self.execute(
749 cmd="h1 /usr/sbin/sshd -D&",
750 prompt="mininet>",
751 timeout=10 )
752 response = self.execute(
753 cmd="h4 /usr/sbin/sshd -D&",
754 prompt="mininet>",
755 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700756 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800757 vars( self )[ key ] = connectargs[ key ]
758 response = self.execute(
759 cmd="xterm h1 h4 ",
760 prompt="mininet>",
761 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800762 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800763 main.log.error( self.name + ": EOF exception found" )
764 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700765 main.cleanup()
766 main.exit()
adminbae64d82013-08-01 10:50:15 -0700767 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800768 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700769 if self.flag == 0:
770 self.flag = 1
771 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800772 else:
adminbae64d82013-08-01 10:50:15 -0700773 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800774
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700775 def moveHost( self, host, oldSw, newSw ):
Jon Hall53c5e662016-04-13 16:06:56 -0700776 """
777 Moves a host from one switch to another on the fly
778 Note: The intf between host and oldSw when detached
779 using detach(), will still show up in the 'net'
780 cmd, because switch.detach() doesn't affect switch.intfs[]
781 ( which is correct behavior since the interfaces
782 haven't moved ).
783 """
784 if self.handle:
785 try:
786 # Bring link between oldSw-host down
787 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
788 "'," + "'down')"
789 print "cmd1= ", cmd
790 response = self.execute( cmd=cmd,
791 prompt="mininet>",
792 timeout=10 )
793
794 # Determine hostintf and Oldswitchintf
795 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
796 ")[0]"
797 print "cmd2= ", cmd
798 self.handle.sendline( cmd )
799 self.handle.expect( "mininet>" )
800
801 # Determine ip and mac address of the host-oldSw interface
802 cmd = "px ipaddr = hintf.IP()"
803 print "cmd3= ", cmd
804 self.handle.sendline( cmd )
805 self.handle.expect( "mininet>" )
806
807 cmd = "px macaddr = hintf.MAC()"
808 print "cmd3= ", cmd
809 self.handle.sendline( cmd )
810 self.handle.expect( "mininet>" )
811
812 # Detach interface between oldSw-host
813 cmd = "px " + oldSw + ".detach( sintf )"
814 print "cmd4= ", cmd
815 self.handle.sendline( cmd )
816 self.handle.expect( "mininet>" )
817
818 # Add link between host-newSw
819 cmd = "py net.addLink(" + host + "," + newSw + ")"
820 print "cmd5= ", cmd
821 self.handle.sendline( cmd )
822 self.handle.expect( "mininet>" )
823
824 # Determine hostintf and Newswitchintf
825 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
826 ")[0]"
827 print "cmd6= ", cmd
828 self.handle.sendline( cmd )
829 self.handle.expect( "mininet>" )
830
831 # Attach interface between newSw-host
832 cmd = "px " + newSw + ".attach( sintf )"
833 print "cmd3= ", cmd
834 self.handle.sendline( cmd )
835 self.handle.expect( "mininet>" )
836
837 # Set ipaddress of the host-newSw interface
838 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
839 print "cmd7 = ", cmd
840 self.handle.sendline( cmd )
841 self.handle.expect( "mininet>" )
842
843 # Set macaddress of the host-newSw interface
844 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
845 print "cmd8 = ", cmd
846 self.handle.sendline( cmd )
847 self.handle.expect( "mininet>" )
848
849 cmd = "net"
850 print "cmd9 = ", cmd
851 self.handle.sendline( cmd )
852 self.handle.expect( "mininet>" )
853 print "output = ", self.handle.before
854
855 # Determine ipaddress of the host-newSw interface
856 cmd = host + " ifconfig"
857 print "cmd10= ", cmd
858 self.handle.sendline( cmd )
859 self.handle.expect( "mininet>" )
860 print "ifconfig o/p = ", self.handle.before
861
862 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700863
864 except pexpect.TIMEOUT:
865 main.log.error(self.name + ": TIMEOUT exception found")
866 main.log.error(self.name + ": " + self.handle.before)
867 main.cleanup()
868 main.exit()
Jon Hall53c5e662016-04-13 16:06:56 -0700869 except pexpect.EOF:
870 main.log.error( self.name + ": EOF exception found" )
871 main.log.error( self.name + ": " + self.handle.before )
872 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700873 except Exception:
874 main.log.exception( self.name + ": Uncaught exception!" )
875 return main.FALSE
Jon Hall53c5e662016-04-13 16:06:56 -0700876
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700877 def moveHostv6( self, host, oldSw, newSw ):
kelvin-onlaba1484582015-02-02 15:46:20 -0800878 """
879 Moves a host from one switch to another on the fly
880 Note: The intf between host and oldSw when detached
881 using detach(), will still show up in the 'net'
882 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700883 ( which is correct behavior since the interfaces
884 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800885 """
886 if self.handle:
887 try:
Jon Hall439c8912016-04-15 02:22:03 -0700888 IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/64"
kelvin-onlaba1484582015-02-02 15:46:20 -0800889 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700890 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800891 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800892 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800893 response = self.execute( cmd=cmd,
894 prompt="mininet>",
895 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700896
kelvin-onlaba1484582015-02-02 15:46:20 -0800897 # Determine hostintf and Oldswitchintf
898 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800899 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800900 print "cmd2= ", cmd
901 self.handle.sendline( cmd )
902 self.handle.expect( "mininet>" )
903
shahshreya73537862015-02-11 15:15:24 -0800904 # Determine ip and mac address of the host-oldSw interface
Jon Hall439c8912016-04-15 02:22:03 -0700905 cmd = "px ipaddr = " + str(IP)
kelvin-onlaba1484582015-02-02 15:46:20 -0800906 print "cmd3= ", cmd
907 self.handle.sendline( cmd )
908 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800909
910 cmd = "px macaddr = hintf.MAC()"
911 print "cmd3= ", cmd
912 self.handle.sendline( cmd )
913 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700914
kelvin-onlaba1484582015-02-02 15:46:20 -0800915 # Detach interface between oldSw-host
916 cmd = "px " + oldSw + ".detach( sintf )"
917 print "cmd4= ", cmd
918 self.handle.sendline( cmd )
919 self.handle.expect( "mininet>" )
920
921 # Add link between host-newSw
922 cmd = "py net.addLink(" + host + "," + newSw + ")"
923 print "cmd5= ", cmd
924 self.handle.sendline( cmd )
925 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700926
kelvin-onlaba1484582015-02-02 15:46:20 -0800927 # Determine hostintf and Newswitchintf
928 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800929 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800930 print "cmd6= ", cmd
931 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700932 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800933
934 # Attach interface between newSw-host
935 cmd = "px " + newSw + ".attach( sintf )"
Jon Hall439c8912016-04-15 02:22:03 -0700936 print "cmd6= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800937 self.handle.sendline( cmd )
938 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800939
940 # Set macaddress of the host-newSw interface
941 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
Jon Hall439c8912016-04-15 02:22:03 -0700942 print "cmd7 = ", cmd
943 self.handle.sendline( cmd )
944 self.handle.expect( "mininet>" )
945
946 # Set ipaddress of the host-newSw interface
947 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
shahshreya73537862015-02-11 15:15:24 -0800948 print "cmd8 = ", cmd
949 self.handle.sendline( cmd )
950 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700951
Jon Hall439c8912016-04-15 02:22:03 -0700952 cmd = host + " ifconfig"
953 print "cmd9 =",cmd
954 response = self.execute( cmd = cmd, prompt="mininet>" ,timeout=10 )
955 print response
956 pattern = "h\d-eth([\w])"
Jeremyd9e4eb12016-04-13 12:09:06 -0700957 ipAddressSearch = re.search( pattern, response )
Jon Hall439c8912016-04-15 02:22:03 -0700958 print ipAddressSearch.group(1)
959 intf= host + "-eth" + str(ipAddressSearch.group(1))
960 cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
961 print "cmd10 = ", cmd
962 self.handle.sendline( cmd )
963 self.handle.expect( "mininet>" )
964
kelvin-onlaba1484582015-02-02 15:46:20 -0800965 cmd = "net"
Jon Hall439c8912016-04-15 02:22:03 -0700966 print "cmd11 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800967 self.handle.sendline( cmd )
968 self.handle.expect( "mininet>" )
969 print "output = ", self.handle.before
970
971 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800972 cmd = host + " ifconfig"
Jon Hall439c8912016-04-15 02:22:03 -0700973 print "cmd12= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800974 self.handle.sendline( cmd )
975 self.handle.expect( "mininet>" )
976 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700977
kelvin-onlaba1484582015-02-02 15:46:20 -0800978 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700979 except pexpect.TIMEOUT:
980 main.log.error(self.name + ": TIMEOUT exception found")
981 main.log.error(self.name + ": " + self.handle.before)
982 main.cleanup()
983 main.exit()
kelvin-onlaba1484582015-02-02 15:46:20 -0800984 except pexpect.EOF:
985 main.log.error( self.name + ": EOF exception found" )
986 main.log.error( self.name + ": " + self.handle.before )
987 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -0700988 except Exception:
989 main.log.exception( self.name + ": Uncaught exception!" )
990 return main.FALSE
kelvin-onlaba1484582015-02-02 15:46:20 -0800991
Jon Hall7eb38402015-01-08 17:19:54 -0800992 def changeIP( self, host, intf, newIP, newNetmask ):
993 """
994 Changes the ip address of a host on the fly
995 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800996 if self.handle:
997 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800998 cmd = host + " ifconfig " + intf + " " + \
999 newIP + " " + 'netmask' + " " + newNetmask
1000 self.handle.sendline( cmd )
1001 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001002 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001003 main.log.info( "response = " + response )
1004 main.log.info(
1005 "Ip of host " +
1006 host +
1007 " changed to new IP " +
1008 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -08001009 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001010 except pexpect.TIMEOUT:
1011 main.log.error(self.name + ": TIMEOUT exception found")
1012 main.log.error(self.name + ": " + self.handle.before)
1013 main.cleanup()
1014 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001015 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001016 main.log.error( self.name + ": EOF exception found" )
1017 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001018 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001019 except Exception:
1020 main.log.exception( self.name + ": Uncaught exception!" )
1021 main.cleanup()
1022 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001023
Jon Hall7eb38402015-01-08 17:19:54 -08001024 def changeDefaultGateway( self, host, newGW ):
1025 """
1026 Changes the default gateway of a host
1027 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -08001028 if self.handle:
1029 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001030 cmd = host + " route add default gw " + newGW
1031 self.handle.sendline( cmd )
1032 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001033 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001034 main.log.info( "response = " + response )
1035 main.log.info(
1036 "Default gateway of host " +
1037 host +
1038 " changed to " +
1039 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -08001040 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001041 except pexpect.TIMEOUT:
1042 main.log.error(self.name + ": TIMEOUT exception found")
1043 main.log.error(self.name + ": " + self.handle.before)
1044 main.cleanup()
1045 main.exit()
shahshreyae6c7cf42014-11-26 16:39:01 -08001046 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001047 main.log.error( self.name + ": EOF exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -08001049 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001050 except Exception:
1051 main.log.exception( self.name + ": Uncaught exception!" )
1052 main.cleanup()
1053 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001054
Jon Hall7eb38402015-01-08 17:19:54 -08001055 def addStaticMACAddress( self, host, GW, macaddr ):
1056 """
Jon Hallefbd9792015-03-05 16:11:36 -08001057 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -08001058 if self.handle:
1059 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001060 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
1061 cmd = host + " arp -s " + GW + " " + macaddr
1062 self.handle.sendline( cmd )
1063 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001064 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001065 main.log.info( "response = " + response )
1066 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -08001067 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -08001068 GW +
1069 " changed to " +
1070 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -08001071 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001072 except pexpect.TIMEOUT:
1073 main.log.error(self.name + ": TIMEOUT exception found")
1074 main.log.error(self.name + ": " + self.handle.before)
1075 main.cleanup()
1076 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001077 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001078 main.log.error( self.name + ": EOF exception found" )
1079 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001080 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001081 except Exception:
1082 main.log.exception( self.name + ": Uncaught exception!" )
1083 main.cleanup()
1084 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001085
Jon Hall7eb38402015-01-08 17:19:54 -08001086 def verifyStaticGWandMAC( self, host ):
1087 """
1088 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -08001089 if self.handle:
1090 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001091 # h1 arp -an
1092 cmd = host + " arp -an "
1093 self.handle.sendline( cmd )
1094 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -08001095 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -08001096 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -08001097 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001098 except pexpect.TIMEOUT:
1099 main.log.error(self.name + ": TIMEOUT exception found")
1100 main.log.error(self.name + ": " + self.handle.before)
1101 main.cleanup()
1102 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001103 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001106 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001107 except Exception:
1108 main.log.exception( self.name + ": Uncaught exception!" )
1109 main.cleanup()
1110 main.exit()
shahshreyad0c80432014-12-04 16:56:05 -08001111
Jon Hall7eb38402015-01-08 17:19:54 -08001112 def getMacAddress( self, host ):
1113 """
1114 Verifies the host's ip configured or not."""
1115 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001116 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 response = self.execute(
1118 cmd=host +
1119 " ifconfig",
1120 prompt="mininet>",
1121 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001122 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001123 main.log.error( self.name + ": EOF exception found" )
1124 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001125 main.cleanup()
1126 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001127 except Exception:
1128 main.log.exception( self.name + ": Uncaught exception!" )
1129 main.cleanup()
1130 main.exit()
adminbae64d82013-08-01 10:50:15 -07001131
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -07001132 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 macAddressSearch = re.search( pattern, response, re.I )
1134 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001135 main.log.info(
1136 self.name +
1137 ": Mac-Address of Host " +
1138 host +
1139 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 macAddress )
1141 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001142 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001143 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001144
Jon Hall7eb38402015-01-08 17:19:54 -08001145 def getInterfaceMACAddress( self, host, interface ):
1146 """
1147 Return the IP address of the interface on the given host"""
1148 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001149 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001150 response = self.execute( cmd=host + " ifconfig " + interface,
1151 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001152 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001153 main.log.error( self.name + ": EOF exception found" )
1154 main.log.error( self.name + ": " + self.handle.before )
1155 main.cleanup()
1156 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001157 except Exception:
1158 main.log.exception( self.name + ": Uncaught exception!" )
1159 main.cleanup()
1160 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001161
1162 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001163 macAddressSearch = re.search( pattern, response, re.I )
1164 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001165 main.log.info( "No mac address found in %s" % response )
1166 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -08001168 main.log.info(
1169 "Mac-Address of " +
1170 host +
1171 ":" +
1172 interface +
1173 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 macAddress )
1175 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -08001176 else:
1177 main.log.error( "Connection failed to the host" )
1178
sathishmad953462015-12-03 17:42:07 +05301179 def getIPAddress( self, host , proto='IPV4'):
Jon Hall7eb38402015-01-08 17:19:54 -08001180 """
1181 Verifies the host's ip configured or not."""
1182 if self.handle:
1183 try:
1184 response = self.execute(
1185 cmd=host +
1186 " ifconfig",
1187 prompt="mininet>",
1188 timeout=10 )
1189 except pexpect.EOF:
1190 main.log.error( self.name + ": EOF exception found" )
1191 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001192 main.cleanup()
1193 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001194 except Exception:
1195 main.log.exception( self.name + ": Uncaught exception!" )
1196 main.cleanup()
1197 main.exit()
adminbae64d82013-08-01 10:50:15 -07001198
sathishmad953462015-12-03 17:42:07 +05301199 pattern = ''
1200 if proto == 'IPV4':
1201 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
1202 else:
Jon Hall439c8912016-04-15 02:22:03 -07001203 pattern = "inet6\saddr:\s([\w,:]*)/\d+\sScope:Global"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001204 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -08001205 main.log.info(
1206 self.name +
1207 ": IP-Address of Host " +
1208 host +
1209 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 ipAddressSearch.group( 1 ) )
1211 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -08001212 else:
1213 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001214
Jon Hall7eb38402015-01-08 17:19:54 -08001215 def getSwitchDPID( self, switch ):
1216 """
1217 return the datapath ID of the switch"""
1218 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001219 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -07001220 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001221 response = self.execute(
1222 cmd=cmd,
1223 prompt="mininet>",
1224 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001225 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001226 main.log.error( self.name + ": EOF exception found" )
1227 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001228 main.cleanup()
1229 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001230 except Exception:
1231 main.log.exception( self.name + ": Uncaught exception!" )
1232 main.cleanup()
1233 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -08001234 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -08001235 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001236 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001237 main.log.info(
1238 "Couldn't find DPID for switch %s, found: %s" %
1239 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001240 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001241 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001242 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001243 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001244
Jon Hall7eb38402015-01-08 17:19:54 -08001245 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -07001246 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -08001247 self.handle.sendline( "" )
1248 self.expect( "mininet>" )
1249 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -07001250 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001251 response = self.execute(
1252 cmd=cmd,
1253 prompt="mininet>",
1254 timeout=10 )
1255 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -07001256 response = self.handle.before
1257 return response
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001258 except pexpect.TIMEOUT:
1259 main.log.error(self.name + ": TIMEOUT exception found")
1260 main.log.error(self.name + ": " + self.handle.before)
1261 main.cleanup()
1262 main.exit()
admin2580a0e2014-07-29 11:24:34 -07001263 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001264 main.log.error( self.name + ": EOF exception found" )
1265 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -07001266 main.cleanup()
1267 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001268 except Exception:
1269 main.log.exception( self.name + ": Uncaught exception!" )
1270 main.cleanup()
1271 main.exit()
admin2580a0e2014-07-29 11:24:34 -07001272
Jon Hall7eb38402015-01-08 17:19:54 -08001273 def getInterfaces( self, node ):
1274 """
1275 return information dict about interfaces connected to the node"""
1276 if self.handle:
1277 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -08001278 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001279 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -07001280 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001281 response = self.execute(
1282 cmd=cmd,
1283 prompt="mininet>",
1284 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001285 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001286 main.log.error( self.name + ": EOF exception found" )
1287 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001288 main.cleanup()
1289 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception!" )
1292 main.cleanup()
1293 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001294 return response
1295 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001296 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -07001297
Jon Hall7eb38402015-01-08 17:19:54 -08001298 def dump( self ):
1299 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -07001300 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001301 response = self.execute(
1302 cmd='dump',
1303 prompt='mininet>',
1304 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001305 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001306 main.log.error( self.name + ": EOF exception found" )
1307 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001308 main.cleanup()
1309 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001310 except Exception:
1311 main.log.exception( self.name + ": Uncaught exception!" )
1312 main.cleanup()
1313 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -07001314 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001315
Jon Hall7eb38402015-01-08 17:19:54 -08001316 def intfs( self ):
1317 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -07001318 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001319 response = self.execute(
1320 cmd='intfs',
1321 prompt='mininet>',
1322 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001323 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001324 main.log.error( self.name + ": EOF exception found" )
1325 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001326 main.cleanup()
1327 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001328 except Exception:
1329 main.log.exception( self.name + ": Uncaught exception!" )
1330 main.cleanup()
1331 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001332 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001333
Jon Hall7eb38402015-01-08 17:19:54 -08001334 def net( self ):
1335 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -07001336 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001337 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001338 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001339 main.log.error( self.name + ": EOF exception found" )
1340 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001341 main.cleanup()
1342 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001343 except Exception:
1344 main.log.exception( self.name + ": Uncaught exception!" )
1345 main.cleanup()
1346 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001347 return response
Jon Hall7eb38402015-01-08 17:19:54 -08001348
YPZhang81a7d4e2016-04-18 13:10:17 -07001349 def links( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07001350 main.log.info( self.name + ": List network links" )
1351 try:
1352 response = self.execute( cmd='links', prompt='mininet>',
YPZhang81a7d4e2016-04-18 13:10:17 -07001353 timeout=timeout )
Jon Hallafa8a472015-06-12 14:02:42 -07001354 except pexpect.EOF:
1355 main.log.error( self.name + ": EOF exception found" )
1356 main.log.error( self.name + ": " + self.handle.before )
1357 main.cleanup()
1358 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001359 except Exception:
1360 main.log.exception( self.name + ": Uncaught exception!" )
1361 main.cleanup()
1362 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07001363 return response
1364
GlennRC61321f22015-07-16 13:36:54 -07001365 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001366 '''
1367 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -07001368
kelvin-onlab7cce9382015-07-17 10:21:03 -07001369 @parm:
1370 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1371 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1372 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001373 try:
1374 for host1 in hosts:
1375 for host2 in hosts:
1376 if host1 != host2:
1377 if self.iperftcp(host1, host2, timeout) == main.FALSE:
1378 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
1379 except Exception:
1380 main.log.exception( self.name + ": Uncaught exception!" )
1381 main.cleanup()
1382 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001383
1384 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001385 '''
1386 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1387 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001388
kelvin-onlab7cce9382015-07-17 10:21:03 -07001389 @parm:
1390 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1391 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1392 '''
1393 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1394 try:
1395 # Setup the mininet command
1396 cmd1 = 'iperf ' + host1 + " " + host2
1397 self.handle.sendline( cmd1 )
1398 outcome = self.handle.expect( "mininet>", timeout )
1399 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001400
kelvin-onlab7cce9382015-07-17 10:21:03 -07001401 # checks if there are results in the mininet response
1402 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001403 main.log.report(self.name + ": iperf test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001404 # parse the mn results
1405 response = response.split("\r\n")
1406 response = response[len(response)-2]
1407 response = response.split(": ")
1408 response = response[len(response)-1]
1409 response = response.replace("[", "")
1410 response = response.replace("]", "")
1411 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001412
kelvin-onlab7cce9382015-07-17 10:21:03 -07001413 # this is the bandwith two and from the two hosts
1414 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001415
kelvin-onlab7cce9382015-07-17 10:21:03 -07001416 # there should be two elements in the bandwidth list
1417 # ['host1 to host2', 'host2 to host1"]
1418 if len(bandwidth) == 2:
1419 main.log.report(self.name + ": iperf test successful")
1420 return main.TRUE
1421 else:
1422 main.log.error(self.name + ": invalid iperf results")
1423 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001424 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001425 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001426 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001427 except pexpect.TIMEOUT:
Jon Hall3b489db2015-10-05 14:38:37 -07001428 main.log.error( self.name + ": TIMEOUT exception found" )
1429 main.log.error( self.name + " response: " +
Jon Hall892818c2015-10-20 17:58:34 -07001430 repr( self.handle.before ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001431 # NOTE: Send ctrl-c to make sure iperf is done
1432 self.handle.sendline( "\x03" )
1433 self.handle.expect( "Interrupt" )
1434 self.handle.expect( "mininet>" )
GlennRC61321f22015-07-16 13:36:54 -07001435 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001436 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001437 main.log.error( self.name + ": EOF exception found" )
1438 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001439 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001440 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001441 except Exception:
1442 main.log.exception( self.name + ": Uncaught exception!" )
1443 main.cleanup()
1444 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001445
Jon Hall439c8912016-04-15 02:22:03 -07001446 def iperftcpipv6(self, host1="h1", host2="h2", timeout=50):
1447 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1448 try:
1449 IP1 = self.getIPAddress( host1, proto='IPV6' )
1450 cmd1 = host1 +' iperf -V -sD -B '+ str(IP1)
1451 self.handle.sendline( cmd1 )
1452 outcome1 = self.handle.expect( "mininet>")
1453 cmd2 = host2 +' iperf -V -c '+ str(IP1) +' -t 5'
1454 self.handle.sendline( cmd2 )
1455 outcome2 = self.handle.expect( "mininet>")
1456 response1 = self.handle.before
1457 response2 = self.handle.after
1458 print response1,response2
1459 pattern = "connected with "+ str(IP1)
1460 if pattern in response1:
1461 main.log.report(self.name + ": iperf test completed")
1462 return main.TRUE
1463 else:
1464 main.log.error( self.name + ": iperf test failed" )
1465 return main.FALSE
1466 except pexpect.TIMEOUT:
1467 main.log.error( self.name + ": TIMEOUT exception found" )
1468 main.log.error( self.name + " response: " + repr( self.handle.before ) )
1469 self.handle.sendline( "\x03" )
1470 self.handle.expect( "Interrupt" )
1471 self.handle.expect( "mininet>" )
1472 return main.FALSE
1473 except pexpect.EOF:
1474 main.log.error( self.name + ": EOF exception found" )
1475 main.log.error( self.name + ": " + self.handle.before )
1476 main.cleanup()
1477 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001478 except Exception:
1479 main.log.exception( self.name + ": Uncaught exception!" )
1480 main.cleanup()
1481 main.exit()
Jon Hall439c8912016-04-15 02:22:03 -07001482
GlennRC61321f22015-07-16 13:36:54 -07001483 def iperfudpAll(self, hosts, bandwidth="10M"):
1484 '''
1485 Runs the iperfudp function with a given set of hosts and specified
1486 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001487
GlennRC61321f22015-07-16 13:36:54 -07001488 @param:
1489 bandwidth: the targeted bandwidth, in megabits ('M')
1490 '''
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001491 try:
1492 for host1 in hosts:
1493 for host2 in hosts:
1494 if host1 != host2:
1495 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1496 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1497 except TypeError:
1498 main.log.exception(self.name + ": Object not as expected")
1499 return main.FALSE
1500 except Exception:
1501 main.log.exception( self.name + ": Uncaught exception!" )
1502 main.cleanup()
1503 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001504
1505 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1506
kelvin-onlab7cce9382015-07-17 10:21:03 -07001507 '''
1508 Creates an iperf UDP test with a specific bandwidth.
1509 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001510
kelvin-onlab7cce9382015-07-17 10:21:03 -07001511 @param:
1512 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1513 '''
1514 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1515 try:
1516 # setup the mininet command
1517 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1518 self.handle.sendline(cmd)
1519 self.handle.expect("mininet>")
1520 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001521
kelvin-onlab7cce9382015-07-17 10:21:03 -07001522 # check if there are in results in the mininet response
1523 if "Results:" in response:
Jon Hall892818c2015-10-20 17:58:34 -07001524 main.log.report(self.name + ": iperfudp test completed")
kelvin-onlab7cce9382015-07-17 10:21:03 -07001525 # parse the results
1526 response = response.split("\r\n")
1527 response = response[len(response)-2]
1528 response = response.split(": ")
1529 response = response[len(response)-1]
1530 response = response.replace("[", "")
1531 response = response.replace("]", "")
1532 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001533
kelvin-onlab7cce9382015-07-17 10:21:03 -07001534 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001535
kelvin-onlab7cce9382015-07-17 10:21:03 -07001536 # check to see if there are at least three entries
1537 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1538 if len(mnBandwidth) == 3:
1539 # if one entry is blank then something is wrong
1540 for item in mnBandwidth:
1541 if item == "":
1542 main.log.error(self.name + ": Could not parse iperf output")
1543 main.log.error(self.name + ": invalid iperfudp results")
1544 return main.FALSE
1545 # otherwise results are vaild
1546 main.log.report(self.name + ": iperfudp test successful")
1547 return main.TRUE
1548 else:
1549 main.log.error(self.name + ": invalid iperfudp results")
1550 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001551
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001552 except pexpect.TIMEOUT:
1553 main.log.error(self.name + ": TIMEOUT exception found")
1554 main.log.error(self.name + ": " + self.handle.before)
1555 main.cleanup()
1556 main.exit()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001557 except pexpect.EOF:
1558 main.log.error( self.name + ": EOF exception found" )
1559 main.log.error( self.name + ": " + self.handle.before )
1560 main.cleanup()
1561 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001562 except Exception:
1563 main.log.exception( self.name + ": Uncaught exception!" )
1564 main.cleanup()
1565 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001566
Jon Hall7eb38402015-01-08 17:19:54 -08001567 def nodes( self ):
1568 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001569 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001570 response = self.execute(
1571 cmd='nodes',
1572 prompt='mininet>',
1573 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001574 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001575 main.log.error( self.name + ": EOF exception found" )
1576 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001577 main.cleanup()
1578 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001579 except Exception:
1580 main.log.exception( self.name + ": Uncaught exception!" )
1581 main.cleanup()
1582 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001583 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001584
Jon Hall7eb38402015-01-08 17:19:54 -08001585 def pingpair( self ):
1586 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001587 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001588 response = self.execute(
1589 cmd='pingpair',
1590 prompt='mininet>',
1591 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001592 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001593 main.log.error( self.name + ": EOF exception found" )
1594 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001595 main.cleanup()
1596 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001597 except Exception:
1598 main.log.exception( self.name + ": Uncaught exception!" )
1599 main.cleanup()
1600 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001601
Jon Hall7eb38402015-01-08 17:19:54 -08001602 if re.search( ',\s0\%\spacket\sloss', response ):
1603 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
adminbae64d82013-08-01 10:50:15 -07001604 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001605 else:
1606 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
adminbae64d82013-08-01 10:50:15 -07001607 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001608
Jon Hall7eb38402015-01-08 17:19:54 -08001609 def link( self, **linkargs ):
1610 """
GlennRCed771242016-01-13 17:02:47 -08001611 Bring link( s ) between two nodes up or down
1612 """
Jon Hall6094a362014-04-11 14:46:56 -07001613 try:
GlennRCed771242016-01-13 17:02:47 -08001614 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
1615 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1616 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1617 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1618
1619 main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
1620 cmd = "link {} {} {}".format( end1, end2, option )
1621 self.handle.sendline( cmd )
Jon Hall7eb38402015-01-08 17:19:54 -08001622 self.handle.expect( "mininet>" )
GlennRCed771242016-01-13 17:02:47 -08001623 response = self.handle.before
1624 main.log.info( response )
1625
1626 return main.TRUE
1627 except pexpect.TIMEOUT:
1628 main.log.exception( self.name + ": Command timed out" )
1629 return None
Jon Hallfbc828e2015-01-06 17:30:19 -08001630 except pexpect.EOF:
GlennRCed771242016-01-13 17:02:47 -08001631 main.log.exception( self.name + ": connection closed." )
Jon Hall6094a362014-04-11 14:46:56 -07001632 main.cleanup()
1633 main.exit()
GlennRCed771242016-01-13 17:02:47 -08001634 except Exception:
1635 main.log.exception( self.name + ": Uncaught exception!" )
1636 main.cleanup()
1637 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001638
pingping-lin8244a3b2015-09-16 13:36:56 -07001639 def switch( self, **switchargs ):
1640 """
1641 start/stop a switch
1642 """
1643 args = utilities.parse_args( [ "SW", "OPTION" ], **switchargs )
1644 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1645 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1646 command = "switch " + str( sw ) + " " + str( option )
1647 main.log.info( command )
1648 try:
1649 self.handle.sendline( command )
1650 self.handle.expect( "mininet>" )
1651 except pexpect.TIMEOUT:
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001652 main.log.error(self.name + ": TIMEOUT exception found")
1653 main.log.error(self.name + ": " + self.handle.before)
pingping-lin8244a3b2015-09-16 13:36:56 -07001654 main.cleanup()
1655 main.exit()
1656 except pexpect.EOF:
1657 main.log.error( self.name + ": EOF exception found" )
1658 main.log.error( self.name + ": " + self.handle.before )
1659 main.cleanup()
1660 main.exit()
1661 return main.TRUE
1662
pingping-lin5bb663b2015-09-24 11:47:50 -07001663 def node( self, nodeName, commandStr ):
1664 """
1665 Carry out a command line on a given node
1666 @parm:
1667 nodeName: the node name in Mininet testbed
1668 commandStr: the command line will be carried out on the node
1669 Example: main.Mininet.node( nodeName="h1", commandStr="ls" )
1670 """
1671 command = str( nodeName ) + " " + str( commandStr )
1672 main.log.info( command )
1673
1674 try:
1675 response = self.execute( cmd = command, prompt = "mininet>" )
1676 if re.search( "Unknown command", response ):
1677 main.log.warn( response )
1678 return main.FALSE
Jon Hall9ed8f372016-02-24 17:34:07 -08001679 if re.search( "Permission denied", response ):
1680 main.log.warn( response )
1681 return main.FALSE
pingping-lin5bb663b2015-09-24 11:47:50 -07001682 except pexpect.EOF:
1683 main.log.error( self.name + ": EOF exception found" )
1684 main.log.error( self.name + ": " + self.handle.before )
1685 main.cleanup()
1686 main.exit()
1687 main.log.info( " response is :" )
1688 main.log.info( response )
1689 return response
1690
Jon Hall7eb38402015-01-08 17:19:54 -08001691 def yank( self, **yankargs ):
1692 """
1693 yank a mininet switch interface to a host"""
1694 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001695 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001696 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1697 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1698 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001699 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001700 response = self.execute(
1701 cmd=command,
1702 prompt="mininet>",
1703 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001704 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001705 main.log.error( self.name + ": EOF exception found" )
1706 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001707 main.cleanup()
1708 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001709 except Exception:
1710 main.log.exception( self.name + ": Uncaught exception!" )
1711 main.cleanup()
1712 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001713 return main.TRUE
1714
Jon Hall7eb38402015-01-08 17:19:54 -08001715 def plug( self, **plugargs ):
1716 """
1717 plug the yanked mininet switch interface to a switch"""
1718 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001719 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001720 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1721 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1722 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001723 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001724 response = self.execute(
1725 cmd=command,
1726 prompt="mininet>",
1727 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001728 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001729 main.log.error( self.name + ": EOF exception found" )
1730 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001731 main.cleanup()
1732 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001733 except Exception:
1734 main.log.exception( self.name + ": Uncaught exception!" )
1735 main.cleanup()
1736 main.exit()
adminbae64d82013-08-01 10:50:15 -07001737 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001738
Jon Hall7eb38402015-01-08 17:19:54 -08001739 def dpctl( self, **dpctlargs ):
1740 """
1741 Run dpctl command on all switches."""
1742 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001743 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001744 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1745 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1746 command = "dpctl " + cmd + " " + str( cmdargs )
1747 try:
1748 response = self.execute(
1749 cmd=command,
1750 prompt="mininet>",
1751 timeout=10 )
1752 except pexpect.EOF:
1753 main.log.error( self.name + ": EOF exception found" )
1754 main.log.error( self.name + ": " + self.handle.before )
1755 main.cleanup()
1756 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001757 except Exception:
1758 main.log.exception( self.name + ": Uncaught exception!" )
1759 main.cleanup()
1760 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001761 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001762
kelvin-onlabd3b64892015-01-20 13:26:24 -08001763 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001764 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001765 # version from MN and not some other file
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001766 try:
1767 fileInput = path + '/lib/Mininet/INSTALL'
1768 version = super( Mininet, self ).getVersion()
1769 pattern = 'Mininet\s\w\.\w\.\w\w*'
1770 for line in open( fileInput, 'r' ).readlines():
1771 result = re.match( pattern, line )
1772 if result:
1773 version = result.group( 0 )
1774 return version
1775 except Exception:
1776 main.log.exception( self.name + ": Uncaught exception!" )
1777 main.cleanup()
1778 main.exit()
adminbae64d82013-08-01 10:50:15 -07001779
kelvin-onlabd3b64892015-01-20 13:26:24 -08001780 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001781 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001782 Parameters:
1783 sw: The name of an OVS switch. Example "s1"
1784 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001785 The output of the command from the mininet cli
1786 or main.FALSE on timeout"""
1787 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001788 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001789 response = self.execute(
1790 cmd=command,
1791 prompt="mininet>",
1792 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001793 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001794 return response
admin2a9548d2014-06-17 14:08:07 -07001795 else:
1796 return main.FALSE
1797 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001798 main.log.error( self.name + ": EOF exception found" )
1799 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001800 main.cleanup()
1801 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001802 except Exception:
1803 main.log.exception( self.name + ": Uncaught exception!" )
1804 main.cleanup()
1805 main.exit()
adminbae64d82013-08-01 10:50:15 -07001806
Charles Chan029be652015-08-24 01:46:10 +08001807 def assignSwController( self, sw, ip, port="6653", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001808 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001809 Description:
1810 Assign switches to the controllers ( for ovs use only )
1811 Required:
1812 sw - Name of the switch. This can be a list or a string.
1813 ip - Ip addresses of controllers. This can be a list or a string.
1814 Optional:
Charles Chan029be652015-08-24 01:46:10 +08001815 port - ONOS use port 6653, if no list of ports is passed, then
1816 the all the controller will use 6653 as their port number
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001817 ptcp - ptcp number, This can be a string or a list that has
1818 the same length as switch. This is optional and not required
1819 when using ovs switches.
1820 NOTE: If switches and ptcp are given in a list type they should have the
1821 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1822 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001823
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001824 Return:
1825 Returns main.TRUE if mininet correctly assigned switches to
1826 controllers, otherwise it will return main.FALSE or an appropriate
1827 exception(s)
1828 """
1829 assignResult = main.TRUE
1830 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001831 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001832 command = "sh ovs-vsctl set-controller "
1833 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001834 try:
1835 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001836 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001837 if isinstance( port, types.StringType ) or \
1838 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001839 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001840 elif isinstance( port, types.ListType ):
1841 main.log.error( self.name + ": Only one controller " +
1842 "assigned and a list of ports has" +
1843 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001844 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001845 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001846 main.log.error( self.name + ": Invalid controller port " +
1847 "number. Please specify correct " +
1848 "controller port" )
1849 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001850
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001851 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001852 if isinstance( port, types.StringType ) or \
1853 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001854 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001855 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1856 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001857 elif isinstance( port, types.ListType ):
1858 if ( len( ip ) != len( port ) ):
1859 main.log.error( self.name + ": Port list = " +
1860 str( len( port ) ) +
1861 "should be the same as controller" +
1862 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001863 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001864 else:
1865 onosIp = ""
1866 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001867 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1868 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001869 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001870 main.log.error( self.name + ": Invalid controller port " +
1871 "number. Please specify correct " +
1872 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001873 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001874 else:
1875 main.log.error( self.name + ": Invalid ip address" )
1876 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001877
1878 if isinstance( sw, types.StringType ):
1879 command += sw + " "
1880 if ptcp:
1881 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001882 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001883 elif isinstance( ptcp, types.ListType ):
1884 main.log.error( self.name + ": Only one switch is " +
1885 "being set and multiple PTCP is " +
1886 "being passed " )
1887 else:
1888 main.log.error( self.name + ": Invalid PTCP" )
1889 ptcp = ""
1890 command += onosIp
1891 commandList.append( command )
1892
1893 elif isinstance( sw, types.ListType ):
1894 if ptcp:
1895 if isinstance( ptcp, types.ListType ):
1896 if len( ptcp ) != len( sw ):
1897 main.log.error( self.name + ": PTCP length = " +
1898 str( len( ptcp ) ) +
1899 " is not the same as switch" +
1900 " length = " +
1901 str( len( sw ) ) )
1902 return main.FALSE
1903 else:
1904 for switch, ptcpNum in zip( sw, ptcp ):
1905 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001906 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001907 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001908 tempCmd += onosIp
1909 commandList.append( tempCmd )
1910 else:
1911 main.log.error( self.name + ": Invalid PTCP" )
1912 return main.FALSE
1913 else:
1914 for switch in sw:
1915 tempCmd = "sh ovs-vsctl set-controller "
1916 tempCmd += switch + " " + onosIp
1917 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001918 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001919 main.log.error( self.name + ": Invalid switch type " )
1920 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001921
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001922 for cmd in commandList:
1923 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001924 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001925 except pexpect.TIMEOUT:
1926 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1927 return main.FALSE
1928 except pexpect.EOF:
1929 main.log.error( self.name + ": EOF exception found" )
1930 main.log.error( self.name + ": " + self.handle.before )
1931 main.cleanup()
1932 main.exit()
1933 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001934 except pexpect.EOF:
1935 main.log.error( self.name + ": EOF exception found" )
1936 main.log.error( self.name + ": " + self.handle.before )
1937 main.cleanup()
1938 main.exit()
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001939 except Exception:
1940 main.log.exception( self.name + ": Uncaught exception!" )
1941 main.cleanup()
1942 main.exit()
adminbae64d82013-08-01 10:50:15 -07001943
kelvin-onlabd3b64892015-01-20 13:26:24 -08001944 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001945 """
1946 Removes the controller target from sw"""
1947 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001948 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001949 response = self.execute(
1950 cmd=command,
1951 prompt="mininet>",
1952 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001953 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001954 main.log.error( self.name + ": EOF exception found" )
1955 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001956 main.cleanup()
1957 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07001958 except Exception:
1959 main.log.exception( self.name + ": Uncaught exception!" )
1960 main.cleanup()
1961 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001962 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001963 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001964
kelvin-onlabd3b64892015-01-20 13:26:24 -08001965 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001966 """
Jon Hallb1290e82014-11-18 16:17:48 -05001967 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001968 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001969 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001970 NOTE: cannot currently specify what type of switch
1971 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001972 sw = name of the new switch as a string
1973 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001974 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001975 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001976 """
1977 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001978 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001979 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001980 response = self.execute(
1981 cmd=command,
1982 prompt="mininet>",
1983 timeout=10 )
1984 if re.search( "already exists!", response ):
1985 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001986 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001987 elif re.search( "Error", response ):
1988 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001989 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001990 elif re.search( "usage:", response ):
1991 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001992 return main.FALSE
1993 else:
1994 return main.TRUE
1995 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001996 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001997 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001998 main.cleanup()
1999 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002000 except Exception:
2001 main.log.exception( self.name + ": Uncaught exception!" )
2002 main.cleanup()
2003 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002004
kelvin-onlabd3b64892015-01-20 13:26:24 -08002005 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08002006 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08002007 delete a switch from the mininet topology
2008 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002009 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08002010 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08002011 sw = name of the switch as a string
2012 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002013 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05002014 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002015 response = self.execute(
2016 cmd=command,
2017 prompt="mininet>",
2018 timeout=10 )
2019 if re.search( "no switch named", response ):
2020 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002021 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002022 elif re.search( "Error", response ):
2023 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002024 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002025 elif re.search( "usage:", response ):
2026 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002027 return main.FALSE
2028 else:
2029 return main.TRUE
2030 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002031 main.log.error( self.name + ": EOF exception found" )
2032 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002033 main.cleanup()
2034 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002035 except Exception:
2036 main.log.exception( self.name + ": Uncaught exception!" )
2037 main.cleanup()
2038 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002039
You Wangdb8cd0a2016-05-26 15:19:45 -07002040 def getSwitchRandom( self, timeout=60, nonCut=True ):
2041 """
2042 Randomly get a switch from Mininet topology.
2043 If nonCut is True, it gets a list of non-cut switches (the deletion
2044 of a non-cut switch will not increase the number of connected
2045 components of a graph) and randomly returns one of them, otherwise
2046 it just randomly returns one switch from all current switches in
2047 Mininet.
2048 Returns the name of the chosen switch.
2049 """
2050 import random
2051 candidateSwitches = []
2052 try:
2053 if not nonCut:
2054 switches = self.getSwitches( timeout=timeout )
2055 assert len( switches ) != 0
2056 for switchName in switches.keys():
2057 candidateSwitches.append( switchName )
2058 else:
2059 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2060 if graphDict == None:
2061 return None
2062 self.graph.update( graphDict )
2063 candidateSwitches = self.graph.getNonCutVertices()
2064 if candidateSwitches == None:
2065 return None
2066 elif len( candidateSwitches ) == 0:
2067 main.log.info( self.name + ": No candidate switch for deletion" )
2068 return None
2069 else:
2070 switch = random.sample( candidateSwitches, 1 )
2071 return switch[ 0 ]
2072 except KeyError:
2073 main.log.exception( self.name + ": KeyError exception found" )
2074 return None
2075 except AssertionError:
2076 main.log.exception( self.name + ": AssertionError exception found" )
2077 return None
2078 except Exception:
2079 main.log.exception( self.name + ": Uncaught exception" )
2080 return None
2081
2082 def delSwitchRandom( self, timeout=60, nonCut=True ):
2083 """
2084 Randomly delete a switch from Mininet topology.
2085 If nonCut is True, it gets a list of non-cut switches (the deletion
2086 of a non-cut switch will not increase the number of connected
2087 components of a graph) and randomly chooses one for deletion,
2088 otherwise it just randomly delete one switch from all current
2089 switches in Mininet.
2090 Returns the name of the deleted switch
2091 """
2092 try:
2093 switch = self.getSwitchRandom( timeout, nonCut )
2094 if switch == None:
2095 return None
2096 else:
2097 deletionResult = self.delSwitch( switch )
2098 if deletionResult:
2099 return switch
2100 else:
2101 return None
2102 except Exception:
2103 main.log.exception( self.name + ": Uncaught exception" )
2104 return None
2105
kelvin-onlabd3b64892015-01-20 13:26:24 -08002106 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002107 """
2108 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002109 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002110 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002111 NOTE: cannot currently specify what type of link
2112 required params:
2113 node1 = the string node name of the first endpoint of the link
2114 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08002115 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002116 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002117 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002118 response = self.execute(
2119 cmd=command,
2120 prompt="mininet>",
2121 timeout=10 )
2122 if re.search( "doesnt exist!", response ):
2123 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002124 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002125 elif re.search( "Error", response ):
2126 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002127 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002128 elif re.search( "usage:", response ):
2129 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002130 return main.FALSE
2131 else:
2132 return main.TRUE
2133 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002134 main.log.error( self.name + ": EOF exception found" )
2135 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002136 main.cleanup()
2137 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002138 except Exception:
2139 main.log.exception( self.name + ": Uncaught exception!" )
2140 main.cleanup()
2141 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002142
kelvin-onlabd3b64892015-01-20 13:26:24 -08002143 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08002144 """
2145 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002146 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002147 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002148 required params:
2149 node1 = the string node name of the first endpoint of the link
2150 node2 = the string node name of the second endpoint of the link
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002151 returns: main.FALSE on an error, else main.TRUE
2152 """
Jon Hallffb386d2014-11-21 13:43:38 -08002153 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05002154 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002155 response = self.execute(
2156 cmd=command,
2157 prompt="mininet>",
2158 timeout=10 )
2159 if re.search( "no node named", response ):
2160 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002161 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002162 elif re.search( "Error", response ):
2163 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002164 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002165 elif re.search( "usage:", response ):
2166 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002167 return main.FALSE
2168 else:
2169 return main.TRUE
2170 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002171 main.log.error( self.name + ": EOF exception found" )
2172 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002173 main.cleanup()
2174 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002175 except Exception:
2176 main.log.exception( self.name + ": Uncaught exception!" )
2177 main.cleanup()
2178 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002179
You Wangdb8cd0a2016-05-26 15:19:45 -07002180 def getLinkRandom( self, timeout=60, nonCut=True ):
2181 """
2182 Randomly get a link from Mininet topology.
2183 If nonCut is True, it gets a list of non-cut links (the deletion
2184 of a non-cut link will not increase the number of connected
2185 component of a graph) and randomly returns one of them, otherwise
2186 it just randomly returns one link from all current links in
2187 Mininet.
2188 Returns the link as a list, e.g. [ 's1', 's2' ]
2189 """
2190 import random
2191 candidateLinks = []
2192 try:
2193 if not nonCut:
2194 links = self.getLinks( timeout=timeout )
2195 assert len( links ) != 0
2196 for link in links:
2197 # Exclude host-switch link
2198 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
2199 continue
2200 candidateLinks.append( [ link[ 'node1' ], link[ 'node2' ] ] )
2201 else:
2202 graphDict = self.getGraphDict( timeout=timeout, useId=False )
2203 if graphDict == None:
2204 return None
2205 self.graph.update( graphDict )
2206 candidateLinks = self.graph.getNonCutEdges()
2207 if candidateLinks == None:
2208 return None
2209 elif len( candidateLinks ) == 0:
2210 main.log.info( self.name + ": No candidate link for deletion" )
2211 return None
2212 else:
2213 link = random.sample( candidateLinks, 1 )
2214 return link[ 0 ]
2215 except KeyError:
2216 main.log.exception( self.name + ": KeyError exception found" )
2217 return None
2218 except AssertionError:
2219 main.log.exception( self.name + ": AssertionError exception found" )
2220 return None
2221 except Exception:
2222 main.log.exception( self.name + ": Uncaught exception" )
2223 return None
2224
2225 def delLinkRandom( self, timeout=60, nonCut=True ):
2226 """
2227 Randomly delete a link from Mininet topology.
2228 If nonCut is True, it gets a list of non-cut links (the deletion
2229 of a non-cut link will not increase the number of connected
2230 component of a graph) and randomly chooses one for deletion,
2231 otherwise it just randomly delete one link from all current links
2232 in Mininet.
2233 Returns the deleted link as a list, e.g. [ 's1', 's2' ]
2234 """
2235 try:
2236 link = self.getLinkRandom( timeout, nonCut )
2237 if link == None:
2238 return None
2239 else:
2240 deletionResult = self.delLink( link[ 0 ], link[ 1 ] )
2241 if deletionResult:
2242 return link
2243 else:
2244 return None
2245 except Exception:
2246 main.log.exception( self.name + ": Uncaught exception" )
2247 return None
2248
kelvin-onlabd3b64892015-01-20 13:26:24 -08002249 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08002250 """
Jon Hallb1290e82014-11-18 16:17:48 -05002251 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002252 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002253 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05002254 NOTE: cannot currently specify what type of host
2255 required params:
2256 hostname = the string hostname
2257 optional key-value params
2258 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08002259 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08002260 """
2261 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08002262 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05002263 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002264 response = self.execute(
2265 cmd=command,
2266 prompt="mininet>",
2267 timeout=10 )
2268 if re.search( "already exists!", response ):
2269 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002270 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002271 elif re.search( "doesnt exists!", response ):
2272 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002273 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002274 elif re.search( "Error", response ):
2275 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002276 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002277 elif re.search( "usage:", response ):
2278 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002279 return main.FALSE
2280 else:
2281 return main.TRUE
2282 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002283 main.log.error( self.name + ": EOF exception found" )
2284 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002285 main.cleanup()
2286 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002287 except Exception:
2288 main.log.exception( self.name + ": Uncaught exception!" )
2289 main.cleanup()
2290 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05002291
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08002293 """
2294 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08002295 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08002296 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08002297 NOTE: this uses a custom mn function
2298 required params:
2299 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08002300 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08002301 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05002302 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002303 response = self.execute(
2304 cmd=command,
2305 prompt="mininet>",
2306 timeout=10 )
2307 if re.search( "no host named", response ):
2308 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002309 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002310 elif re.search( "Error", response ):
2311 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002312 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002313 elif re.search( "usage:", response ):
2314 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05002315 return main.FALSE
2316 else:
2317 return main.TRUE
2318 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002319 main.log.error( self.name + ": EOF exception found" )
2320 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002321 main.cleanup()
2322 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002323 except Exception:
2324 main.log.exception( self.name + ": Uncaught exception!" )
2325 main.cleanup()
2326 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07002327
Jon Hall7eb38402015-01-08 17:19:54 -08002328 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08002329 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002330 Called at the end of the test to stop the mininet and
2331 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08002332 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002333 try:
2334 self.handle.sendline( '' )
2335 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
2336 timeout=2 )
2337 response = main.TRUE
2338 if i == 0:
2339 response = self.stopNet()
2340 elif i == 1:
2341 return main.TRUE
2342 # print "Disconnecting Mininet"
2343 if self.handle:
2344 self.handle.sendline( "exit" )
2345 self.handle.expect( "exit" )
2346 self.handle.expect( "(.*)" )
2347 else:
2348 main.log.error( "Connection failed to the host" )
2349 return response
2350 except pexpect.EOF:
2351 main.log.error( self.name + ": EOF exception found" )
2352 main.log.error( self.name + ": " + self.handle.before )
2353 main.cleanup()
2354 main.exit()
2355 except Exception:
2356 main.log.exception( self.name + ": Uncaught exception!" )
2357 main.cleanup()
2358 main.exit()
kelvin-onlaba1484582015-02-02 15:46:20 -08002359
Jon Halld80cc142015-07-06 13:36:05 -07002360 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002361 """
Jon Hall21270ac2015-02-16 17:59:55 -08002362 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08002363 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08002364 main.FALSE if the pexpect handle does not exist.
2365
Jon Halld61331b2015-02-17 16:35:47 -08002366 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08002367 """
Jon Halld61331b2015-02-17 16:35:47 -08002368 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07002369 response = ''
2370 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07002371 try:
Jon Halld80cc142015-07-06 13:36:05 -07002372 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08002373 i = self.handle.expect( [ 'mininet>',
2374 '\$',
2375 pexpect.EOF,
2376 pexpect.TIMEOUT ],
2377 timeout )
2378 if i == 0:
2379 main.log.info( "Exiting mininet..." )
Jeremyd9e4eb12016-04-13 12:09:06 -07002380 response = self.execute( cmd="exit",
2381 prompt="(.*)",
2382 timeout=120 )
2383 main.log.info( self.name + ": Stopped" )
2384 self.handle.sendline( "sudo mn -c" )
2385 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002386
Jeremyd9e4eb12016-04-13 12:09:06 -07002387 elif i == 1:
kelvin-onlab56a3f462015-02-06 14:04:43 -08002388 main.log.info( " Mininet trying to exit while not " +
2389 "in the mininet prompt" )
Jeremy9cdb1132016-04-19 10:50:40 -07002390 response = main.TRUE
kelvin-onlab56a3f462015-02-06 14:04:43 -08002391 elif i == 2:
2392 main.log.error( "Something went wrong exiting mininet" )
2393 elif i == 3: # timeout
2394 main.log.error( "Something went wrong exiting mininet " +
2395 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07002396
Hari Krishnab35c6d02015-03-18 11:13:51 -07002397 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07002398 self.handle.sendline( "" )
2399 self.handle.expect( '\$' )
2400 self.handle.sendline(
2401 "sudo kill -9 \`ps -ef | grep \"" +
2402 fileName +
2403 "\" | grep -v grep | awk '{print $2}'\`" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002404 except pexpect.TIMEOUT:
2405 main.log.error(self.name + ": TIMEOUT exception found")
2406 main.log.error(self.name + ": " + self.handle.before)
2407 main.cleanup()
2408 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08002409 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002410 main.log.error( self.name + ": EOF exception found" )
2411 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07002412 main.cleanup()
2413 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002414 except Exception:
2415 main.log.exception( self.name + ": Uncaught exception!" )
2416 main.cleanup()
2417 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08002418 else:
2419 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07002420 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08002421 return response
2422
YPZhang26a139e2016-04-25 14:01:55 -07002423 def arping( self, srcHost="", dstHost="10.128.20.211", ethDevice="", output=True, noResult=False ):
kelvin-onlab65782a82015-05-07 14:12:13 -07002424 """
2425 Description:
2426 Sends arp message from mininet host for hosts discovery
2427 Required:
2428 host - hosts name
2429 Optional:
2430 ip - ip address that does not exist in the network so there would
2431 be no reply.
2432 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07002433 if ethDevice:
2434 ethDevice = '-I ' + ethDevice + ' '
YPZhang26a139e2016-04-25 14:01:55 -07002435 cmd = srcHost + " arping -c1 "
2436 if noResult:
2437 cmd += "-w10 " # If we don't want the actural arping result, set -w10, arping will exit after 10 ms.
2438 cmd += ethDevice + dstHost
admin07529932013-11-22 14:58:28 -08002439 try:
YPZhang81a7d4e2016-04-18 13:10:17 -07002440 if output:
2441 main.log.info( "Sending: " + cmd )
kelvin-onlab65782a82015-05-07 14:12:13 -07002442 self.handle.sendline( cmd )
Jon Halla5cb3412015-08-18 14:08:22 -07002443 i = self.handle.expect( [ "mininet>", "arping: " ] )
2444 if i == 0:
2445 return main.TRUE
2446 elif i == 1:
2447 response = self.handle.before + self.handle.after
2448 self.handle.expect( "mininet>" )
2449 response += self.handle.before + self.handle.after
2450 main.log.warn( "Error sending arping, output was: " +
2451 response )
2452 return main.FALSE
2453 except pexpect.TIMEOUT:
2454 main.log.error( self.name + ": TIMEOUT exception found" )
2455 main.log.warn( self.handle.before )
2456 return main.FALSE
kelvin-onlab65782a82015-05-07 14:12:13 -07002457 except pexpect.EOF:
2458 main.log.error( self.name + ": EOF exception found" )
2459 main.log.error( self.name + ": " + self.handle.before )
2460 main.cleanup()
2461 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002462 except Exception:
2463 main.log.exception( self.name + ": Uncaught exception!" )
2464 main.cleanup()
2465 main.exit()
admin07529932013-11-22 14:58:28 -08002466
Jon Hall7eb38402015-01-08 17:19:54 -08002467 def decToHex( self, num ):
2468 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08002469
Jon Hall7eb38402015-01-08 17:19:54 -08002470 def getSwitchFlowCount( self, switch ):
2471 """
2472 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07002473 if self.handle:
2474 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
2475 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002476 response = self.execute(
2477 cmd=cmd,
2478 prompt="mininet>",
2479 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07002480 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002481 main.log.error( self.name + ": EOF exception found" )
2482 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002483 main.cleanup()
2484 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002485 except Exception:
2486 main.log.exception( self.name + ": Uncaught exception!" )
2487 main.cleanup()
2488 main.exit()
admin2a9548d2014-06-17 14:08:07 -07002489 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08002490 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07002491 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08002492 main.log.info(
2493 "Couldn't find flows on switch %s, found: %s" %
2494 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07002495 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002496 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07002497 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002498 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08002499
Jon Hall9ed8f372016-02-24 17:34:07 -08002500 def checkFlows( self, sw, dumpFormat=None ):
2501 if dumpFormat:
2502 command = "sh ovs-ofctl -F " + \
2503 dumpFormat + " dump-flows " + str( sw )
2504 else:
2505 command = "sh ovs-ofctl dump-flows " + str( sw )
2506 try:
2507 response = self.execute(
2508 cmd=command,
2509 prompt="mininet>",
2510 timeout=10 )
2511 return response
2512 except pexpect.EOF:
2513 main.log.error( self.name + ": EOF exception found" )
2514 main.log.error( self.name + ": " + self.handle.before )
2515 main.cleanup()
2516 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002517 except Exception:
2518 main.log.exception( self.name + ": Uncaught exception!" )
2519 main.cleanup()
2520 main.exit()
Jon Hall9ed8f372016-02-24 17:34:07 -08002521
GlennRC68467eb2015-11-16 18:01:01 -08002522 def flowTableComp( self, flowTable1, flowTable2 ):
2523 # This function compares the selctors and treatments of each flow
2524 try:
Jon Hall3c512f72016-05-06 10:44:45 -07002525 assert flowTable1, "flowTable1 is empty or None"
2526 assert flowTable2, "flowTable2 is empty or None"
Jon Hall41d39f12016-04-11 22:54:35 -07002527 returnValue = main.TRUE
GlennRC68467eb2015-11-16 18:01:01 -08002528 if len(flowTable1) != len(flowTable2):
2529 main.log.warn( "Flow table lengths do not match" )
Jon Hall41d39f12016-04-11 22:54:35 -07002530 returnValue = main.FALSE
GlennRCfa65fce2015-12-16 13:16:08 -08002531 dFields = ["n_bytes", "cookie", "n_packets", "duration"]
2532 for flow1, flow2 in zip(flowTable1, flowTable2):
Jon Hallacd1b182015-12-17 11:43:20 -08002533 for field in dFields:
2534 try:
2535 flow1.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002536 except KeyError:
2537 pass
Jon Hallacd1b182015-12-17 11:43:20 -08002538 try:
2539 flow2.pop( field )
Jon Hall41d39f12016-04-11 22:54:35 -07002540 except KeyError:
2541 pass
GlennRC68467eb2015-11-16 18:01:01 -08002542 for i in range( len(flowTable1) ):
GlennRC17bbcf52015-12-14 17:31:50 -08002543 if flowTable1[i] not in flowTable2:
2544 main.log.warn( "Flow tables do not match:" )
2545 main.log.warn( "Old flow:\n{}\n not in new flow table".format( flowTable1[i] ) )
Jon Hall41d39f12016-04-11 22:54:35 -07002546 returnValue = main.FALSE
2547 break
2548 return returnValue
Jon Hall3c512f72016-05-06 10:44:45 -07002549 except AssertionError:
2550 main.log.exception( "Nothing to compare" )
2551 return main.FALSE
GlennRC68467eb2015-11-16 18:01:01 -08002552 except Exception:
2553 main.log.exception( "Uncaught exception!" )
2554 main.cleanup()
2555 main.exit()
Jon Hall9043c902015-07-30 14:23:44 -07002556
GlennRC528ad292015-11-12 10:38:18 -08002557 def parseFlowTable( self, flowTable, version="", debug=True ):
GlennRC956ea742015-11-05 16:14:15 -08002558 '''
2559 Discription: Parses flows into json format.
2560 NOTE: this can parse any string thats separated with commas
2561 Arguments:
2562 Required:
2563 flows: a list of strings that represnt flows
2564 Optional:
2565 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2566 debug: prints out the final result
2567 returns: A list of flows in json format
2568 '''
GlennRC528ad292015-11-12 10:38:18 -08002569 jsonFlowTable = []
You Wang91c37cf2016-05-23 09:39:42 -07002570 try:
2571 for flow in flowTable:
2572 jsonFlow = {}
2573 # split up the fields of the flow
2574 parsedFlow = flow.split(", ")
2575 # get rid of any spaces in front of the field
2576 for i in range( len(parsedFlow) ):
2577 item = parsedFlow[i]
2578 if item[0] == " ":
2579 parsedFlow[i] = item[1:]
2580 # grab the selector and treatment from the parsed flow
2581 # the last element is the selector and the treatment
2582 temp = parsedFlow.pop(-1)
2583 # split up the selector and the treatment
2584 temp = temp.split(" ")
2585 index = 0
2586 # parse the flags
2587 # NOTE: This only parses one flag
2588 flag = {}
2589 if version == "1.3":
2590 flag = {"flag":[temp[index]]}
2591 index += 1
2592 # the first element is the selector and split it up
2593 sel = temp[index]
GlennRC528ad292015-11-12 10:38:18 -08002594 index += 1
You Wang91c37cf2016-05-23 09:39:42 -07002595 sel = sel.split(",")
2596 # the priority is stuck in the selecter so put it back
2597 # in the flow
2598 parsedFlow.append(sel.pop(0))
2599 # parse selector
2600 criteria = []
2601 for item in sel:
2602 # this is the type of the packet e.g. "arp"
2603 if "=" not in item:
2604 criteria.append( {"type":item} )
2605 else:
2606 field = item.split("=")
2607 criteria.append( {field[0]:field[1]} )
2608 selector = {"selector": {"criteria":sorted(criteria)} }
2609 treat = temp[index]
2610 # get rid of the action part e.g. "action=output:2"
2611 # we will add it back later
2612 treat = treat.split("=")
2613 treat.pop(0)
2614 # parse treatment
2615 action = []
2616 for item in treat:
2617 field = item.split(":")
2618 action.append( {field[0]:field[1]} )
2619 # create the treatment field and add the actions
2620 treatment = {"treatment": {"action":sorted(action)} }
2621 # parse the rest of the flow
2622 for item in parsedFlow:
GlennRC528ad292015-11-12 10:38:18 -08002623 field = item.split("=")
You Wang91c37cf2016-05-23 09:39:42 -07002624 jsonFlow.update( {field[0]:field[1]} )
2625 # add the treatment and the selector to the json flow
2626 jsonFlow.update( selector )
2627 jsonFlow.update( treatment )
2628 jsonFlow.update( flag )
GlennRC956ea742015-11-05 16:14:15 -08002629
You Wang91c37cf2016-05-23 09:39:42 -07002630 if debug: main.log.debug( "\033[94mJson flow:\033[0m\n{}\n".format(jsonFlow) )
GlennRC956ea742015-11-05 16:14:15 -08002631
You Wang91c37cf2016-05-23 09:39:42 -07002632 # add the json flow to the json flow table
2633 jsonFlowTable.append( jsonFlow )
GlennRC956ea742015-11-05 16:14:15 -08002634
You Wang91c37cf2016-05-23 09:39:42 -07002635 return jsonFlowTable
2636
2637 except IndexError:
2638 main.log.exception( self.name + ": IndexError found" )
2639 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002640 except pexpect.EOF:
2641 main.log.error( self.name + ": EOF exception found" )
2642 main.log.error( self.name + ": " + self.handle.before )
2643 main.cleanup()
2644 main.exit()
You Wang91c37cf2016-05-23 09:39:42 -07002645 except Exception:
2646 main.log.exception( self.name + ": Uncaught exception!" )
2647 main.cleanup()
2648 main.exit()
GlennRC528ad292015-11-12 10:38:18 -08002649
Jon Hall0a543792015-12-14 11:00:26 -08002650 def getFlowTable( self, sw, version="", debug=False):
GlennRC956ea742015-11-05 16:14:15 -08002651 '''
2652 Discription: Returns the flow table(s) on a switch or switches in a list.
2653 Each element is a flow.
2654 Arguments:
2655 Required:
2656 sw: The switch name ("s1") to retrive the flow table. Can also be
2657 a list of switches.
2658 Optional:
2659 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2660 debug: prints out the final result
2661 '''
2662 try:
2663 switches = []
2664 if type(sw) is list:
Jon Hallca7ac292015-11-11 09:28:12 -08002665 switches.extend(sw)
GlennRC956ea742015-11-05 16:14:15 -08002666 else: switches.append(sw)
2667
2668 flows = []
2669 for s in switches:
2670 cmd = "sh ovs-ofctl dump-flows " + s
2671
GlennRC528ad292015-11-12 10:38:18 -08002672 if "1.0" == version:
2673 cmd += " -F OpenFlow10-table_id"
2674 elif "1.3" == version:
GlennRC956ea742015-11-05 16:14:15 -08002675 cmd += " -O OpenFlow13"
GlennRC956ea742015-11-05 16:14:15 -08002676
2677 main.log.info( "Sending: " + cmd )
2678 self.handle.sendline( cmd )
2679 self.handle.expect( "mininet>" )
2680 response = self.handle.before
2681 response = response.split( "\r\n" )
2682 # dump the first two elements and the last
2683 # the first element is the command that was sent
2684 # the second is the table header
2685 # the last element is empty
2686 response = response[2:-1]
2687 flows.extend( response )
2688
2689 if debug: print "Flows:\n{}\n\n".format(flows)
2690
GlennRC528ad292015-11-12 10:38:18 -08002691 return self.parseFlowTable( flows, version, debug )
GlennRC956ea742015-11-05 16:14:15 -08002692
GlennRC956ea742015-11-05 16:14:15 -08002693 except pexpect.EOF:
2694 main.log.exception( self.name + ": connection closed." )
2695 main.cleanup()
2696 main.exit()
2697 except Exception:
2698 main.log.exception( self.name + ": Uncaught exception!" )
2699 main.cleanup()
2700 main.exit()
2701
2702 def checkFlowId( self, sw, flowId, version="1.3", debug=True ):
2703 '''
2704 Discription: Checks whether the ID provided matches a flow ID in Mininet
2705 Arguments:
2706 Required:
2707 sw: The switch name ("s1") to retrive the flow table. Can also be
2708 a list of switches.
2709 flowId: the flow ID in hex format. Can also be a list of IDs
2710 Optional:
2711 version: The version of OpenFlow. Currently, 1.3 and 1.0 are supported.
2712 debug: prints out the final result
2713 returns: main.TRUE if all IDs are present, otherwise returns main.FALSE
2714 NOTE: prints out IDs that are not present
2715 '''
2716 try:
2717 main.log.info( "Getting flows from Mininet" )
2718 flows = self.getFlowTable( sw, version, debug )
You Wang083ae982016-05-25 09:31:09 -07002719 if flows == None:
2720 return main.ERROR
GlennRC956ea742015-11-05 16:14:15 -08002721
2722 if debug: print "flow ids:\n{}\n\n".format(flowId)
2723
2724 # Check flowId is a list or a string
2725 if type( flowId ) is str:
2726 result = False
2727 for f in flows:
2728 if flowId in f.get( 'cookie' ):
2729 result = True
2730 break
2731 # flowId is a list
2732 else:
2733 result = True
2734 # Get flow IDs from Mininet
2735 mnFlowIds = [ f.get( 'cookie' ) for f in flows ]
2736 # Save the IDs that are not in Mininet
2737 absentIds = [ x for x in flowId if x not in mnFlowIds ]
2738
2739 if debug: print "mn flow ids:\n{}\n\n".format(mnFlowIds)
2740
2741 # Print out the IDs that are not in Mininet
2742 if absentIds:
2743 main.log.warn( "Absent ids: {}".format( absentIds ) )
2744 result = False
2745
2746 return main.TRUE if result else main.FALSE
2747
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002748 except pexpect.EOF:
2749 main.log.error( self.name + ": EOF exception found" )
2750 main.log.error( self.name + ": " + self.handle.before )
2751 main.cleanup()
2752 main.exit()
GlennRC956ea742015-11-05 16:14:15 -08002753 except Exception:
2754 main.log.exception( self.name + ": Uncaught exception!" )
2755 main.cleanup()
2756 main.exit()
2757
2758
Charles Chan029be652015-08-24 01:46:10 +08002759 def startTcpdump( self, filename, intf="eth0", port="port 6653" ):
Jon Hall7eb38402015-01-08 17:19:54 -08002760 """
Jon Hallefbd9792015-03-05 16:11:36 -08002761 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08002762 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07002763 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002764 self.handle.sendline( "" )
2765 self.handle.expect( "mininet>" )
2766 self.handle.sendline(
2767 "sh sudo tcpdump -n -i " +
2768 intf +
2769 " " +
2770 port +
2771 " -w " +
2772 filename.strip() +
2773 " &" )
2774 self.handle.sendline( "" )
2775 i = self.handle.expect( [ 'No\ssuch\device',
2776 'listening\son',
2777 pexpect.TIMEOUT,
2778 "mininet>" ],
2779 timeout=10 )
2780 main.log.warn( self.handle.before + self.handle.after )
2781 self.handle.sendline( "" )
2782 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002783 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08002784 main.log.error(
2785 self.name +
2786 ": tcpdump - No such device exists. " +
2787 "tcpdump attempted on: " +
2788 intf )
admin2a9548d2014-06-17 14:08:07 -07002789 return main.FALSE
2790 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08002791 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07002792 return main.TRUE
2793 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08002794 main.log.error(
2795 self.name +
2796 ": tcpdump command timed out! Check interface name," +
2797 " given interface was: " +
2798 intf )
admin2a9548d2014-06-17 14:08:07 -07002799 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002800 elif i == 3:
2801 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002802 return main.TRUE
2803 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002804 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07002805 return main.FALSE
2806 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002807 main.log.error( self.name + ": EOF exception found" )
2808 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002809 main.cleanup()
2810 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002811 except Exception:
2812 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07002813 main.cleanup()
2814 main.exit()
2815
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08002817 """
2818 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07002819 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002820 self.handle.sendline( "sh sudo pkill tcpdump" )
2821 self.handle.expect( "mininet>" )
2822 self.handle.sendline( "" )
2823 self.handle.expect( "mininet>" )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002824 except pexpect.TIMEOUT:
2825 main.log.error(self.name + ": TIMEOUT exception found")
2826 main.log.error(self.name + ": " + self.handle.before)
2827 main.cleanup()
2828 main.exit()
admin2a9548d2014-06-17 14:08:07 -07002829 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002830 main.log.error( self.name + ": EOF exception found" )
2831 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07002832 main.cleanup()
2833 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002834 except Exception:
2835 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07002836 main.cleanup()
2837 main.exit()
2838
Jon Halld80cc142015-07-06 13:36:05 -07002839 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002840 """
2841 Read ports from a Mininet switch.
2842
2843 Returns a json structure containing information about the
2844 ports of the given switch.
2845 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002846 try:
2847 response = self.getInterfaces( nodeName )
2848 # TODO: Sanity check on response. log if no such switch exists
2849 ports = []
2850 for line in response.split( "\n" ):
2851 if not line.startswith( "name=" ):
2852 continue
2853 portVars = {}
2854 for var in line.split( "," ):
2855 key, value = var.split( "=" )
2856 portVars[ key ] = value
2857 isUp = portVars.pop( 'enabled', "True" )
2858 isUp = "True" in isUp
2859 if verbose:
2860 main.log.info( "Reading switch port %s(%s)" %
2861 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
2862 mac = portVars[ 'mac' ]
2863 if mac == 'None':
2864 mac = None
2865 ips = []
2866 ip = portVars[ 'ip' ]
2867 if ip == 'None':
2868 ip = None
2869 ips.append( ip )
2870 name = portVars[ 'name' ]
2871 if name == 'None':
2872 name = None
2873 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
2874 if name == 'lo':
2875 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
2876 else:
2877 portNo = re.search( portRe, name ).group( 'port' )
2878 ports.append( { 'of_port': portNo,
2879 'mac': str( mac ).replace( '\'', '' ),
2880 'name': name,
2881 'ips': ips,
2882 'enabled': isUp } )
2883 return ports
2884 except pexpect.EOF:
2885 main.log.error( self.name + ": EOF exception found" )
2886 main.log.error( self.name + ": " + self.handle.before )
2887 main.cleanup()
2888 main.exit()
2889 except Exception:
2890 main.log.exception( self.name + ": Uncaught exception!" )
2891 main.cleanup()
2892 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07002893
You Wangdb8cd0a2016-05-26 15:19:45 -07002894 def getOVSPorts( self, nodeName ):
2895 """
2896 Read ports from OVS by executing 'ovs-ofctl dump-ports-desc' command.
2897
2898 Returns a list of dictionaries containing information about each
2899 port of the given switch.
2900 """
2901 command = "sh ovs-ofctl dump-ports-desc " + str( nodeName )
2902 try:
2903 response = self.execute(
2904 cmd=command,
2905 prompt="mininet>",
2906 timeout=10 )
2907 ports = []
2908 if response:
2909 for line in response.split( "\n" ):
2910 # Regex patterns to parse 'ovs-ofctl dump-ports-desc' output
2911 # Example port:
2912 # 1(s1-eth1): addr:ae:60:72:77:55:51
2913 pattern = "(?P<index>\d+)\((?P<name>[^-]+-eth(?P<port>\d+))\):\saddr:(?P<mac>([a-f0-9]{2}:){5}[a-f0-9]{2})"
2914 result = re.search( pattern, line )
2915 if result:
2916 index = result.group( 'index' )
2917 name = result.group( 'name' )
2918 # This port number is extracted from port name
2919 port = result.group( 'port' )
2920 mac = result.group( 'mac' )
2921 ports.append( { 'index': index,
2922 'name': name,
2923 'port': port,
2924 'mac': mac } )
2925 return ports
2926 except pexpect.EOF:
2927 main.log.error( self.name + ": EOF exception found" )
2928 main.log.error( self.name + ": " + self.handle.before )
2929 main.cleanup()
2930 main.exit()
2931 except Exception:
2932 main.log.exception( self.name + ": Uncaught exception!" )
2933 main.cleanup()
2934 main.exit()
2935
Jon Halld80cc142015-07-06 13:36:05 -07002936 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002937 """
2938 Read switches from Mininet.
2939
2940 Returns a dictionary whose keys are the switch names and the value is
2941 a dictionary containing information about the switch.
2942 """
Jon Halla22481b2015-07-28 17:46:01 -07002943 # NOTE: To support new Mininet switch classes, just append the new
2944 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07002945
Jon Halla22481b2015-07-28 17:46:01 -07002946 # Regex patterns to parse 'dump' output
2947 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07002948 # <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 -07002949 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07002950 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
2951 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
2952 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
Ming Yan Shu404f7e72016-07-22 14:37:03 -07002953 try:
2954 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
2955 swRE = r"<(?P<class>" + switchClasses + r")" +\
2956 r"(?P<options>\{.*\})?\s" +\
2957 r"(?P<name>[^:]+)\:\s" +\
2958 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
2959 r"\spid=(?P<pid>(\d)+)"
2960 # Update mn port info
2961 self.update()
2962 output = {}
2963 dump = self.dump().split( "\n" )
2964 for line in dump:
2965 result = re.search( swRE, line, re.I )
2966 if result:
2967 name = result.group( 'name' )
2968 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
2969 pid = result.group( 'pid' )
2970 swClass = result.group( 'class' )
2971 options = result.group( 'options' )
2972 if verbose:
2973 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
2974 ports = self.getPorts( name )
2975 output[ name ] = { "dpid": dpid,
2976 "ports": ports,
2977 "swClass": swClass,
2978 "pid": pid,
2979 "options": options }
2980 return output
2981 except pexpect.EOF:
2982 main.log.error( self.name + ": EOF exception found" )
2983 main.log.error( self.name + ": " + self.handle.before )
2984 main.cleanup()
2985 main.exit()
2986 except Exception:
2987 main.log.exception( self.name + ": Uncaught exception!" )
2988 main.cleanup()
2989 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07002990
Jon Halld80cc142015-07-06 13:36:05 -07002991 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002992 """
2993 Read hosts from Mininet.
2994
2995 Returns a dictionary whose keys are the host names and the value is
2996 a dictionary containing information about the host.
2997 """
2998 # Regex patterns to parse dump output
2999 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07003000 # <Host h1: pid=12725>
3001 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
3002 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
3003 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07003004 # NOTE: Does not correctly match hosts with multi-links
3005 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
3006 # FIXME: Fix that
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003007 try:
3008 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
3009 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
3010 # update mn port info
3011 self.update()
3012 # Get mininet dump
3013 dump = self.dump().split( "\n" )
3014 hosts = {}
3015 for line in dump:
3016 if "Host" in line :
3017 result = re.search( hostRE, line )
3018 name = result.group( 'name' )
3019 interfaces = []
3020 response = self.getInterfaces( name )
3021 # Populate interface info
3022 for line in response.split( "\n" ):
3023 if line.startswith( "name=" ):
3024 portVars = {}
3025 for var in line.split( "," ):
3026 key, value = var.split( "=" )
3027 portVars[ key ] = value
3028 isUp = portVars.pop( 'enabled', "True" )
3029 isUp = "True" in isUp
3030 if verbose:
3031 main.log.info( "Reading host port %s(%s)" %
3032 ( portVars[ 'name' ],
3033 portVars[ 'mac' ] ) )
3034 mac = portVars[ 'mac' ]
3035 if mac == 'None':
3036 mac = None
3037 ips = []
3038 ip = portVars[ 'ip' ]
3039 if ip == 'None':
3040 ip = None
3041 ips.append( ip )
3042 intfName = portVars[ 'name' ]
3043 if name == 'None':
3044 name = None
3045 interfaces.append( {
3046 "name": intfName,
3047 "ips": ips,
3048 "mac": str( mac ),
3049 "isUp": isUp } )
3050 hosts[ name ] = { "interfaces": interfaces }
3051 return hosts
3052 except pexpect.EOF:
3053 main.log.error( self.name + ": EOF exception found" )
3054 main.log.error( self.name + ": " + self.handle.before )
3055 main.cleanup()
3056 main.exit()
3057 except Exception:
3058 main.log.exception( self.name + ": Uncaught exception!" )
3059 main.cleanup()
3060 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07003061
YPZhang81a7d4e2016-04-18 13:10:17 -07003062 def getLinks( self, timeout=20 ):
Jon Hallafa8a472015-06-12 14:02:42 -07003063 """
3064 Gathers information about current Mininet links. These links may not
3065 be up if one of the ports is down.
3066
3067 Returns a list of dictionaries with link endpoints.
3068
3069 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07003070 { 'node1': str( node1 name )
3071 'node2': str( node2 name )
3072 'port1': str( port1 of_port )
3073 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07003074 Note: The port number returned is the eth#, not necessarily the of_port
3075 number. In Mininet, for OVS switch, these should be the same. For
3076 hosts, this is just the eth#.
3077 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003078 try:
3079 self.update()
3080 response = self.links(timeout=timeout).split( '\n' )
Jon Hallafa8a472015-06-12 14:02:42 -07003081
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003082 # Examples:
3083 # s1-eth3<->s2-eth1 (OK OK)
3084 # s13-eth3<->h27-eth0 (OK OK)
3085 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
3086 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
3087 links = []
3088 for line in response:
3089 match = re.search( linkRE, line )
3090 if match:
3091 node1 = match.group( 'node1' )
3092 node2 = match.group( 'node2' )
3093 port1 = match.group( 'port1' )
3094 port2 = match.group( 'port2' )
3095 links.append( { 'node1': node1,
3096 'node2': node2,
3097 'port1': port1,
3098 'port2': port2 } )
3099 return links
3100
3101 except pexpect.EOF:
3102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
3104 main.cleanup()
3105 main.exit()
3106 except Exception:
3107 main.log.exception( self.name + ": Uncaught exception!" )
3108 main.cleanup()
3109 main.exit()
Jon Hallafa8a472015-06-12 14:02:42 -07003110
3111 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003112 """
3113 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07003114 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04003115
Jon Hallafa8a472015-06-12 14:02:42 -07003116 Dependencies:
3117 1. numpy - "sudo pip install numpy"
3118 """
3119 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04003120 # created sorted list of dpid's in MN and ONOS for comparison
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003121 try:
3122 mnDPIDs = []
3123 for swName, switch in switches.iteritems():
3124 mnDPIDs.append( switch[ 'dpid' ].lower() )
3125 mnDPIDs.sort()
3126 if switchesJson == "": # if rest call fails
3127 main.log.error(
3128 self.name +
3129 ".compareSwitches(): Empty JSON object given from ONOS" )
3130 return main.FALSE
3131 onos = switchesJson
3132 onosDPIDs = []
3133 for switch in onos:
3134 if switch[ 'available' ]:
3135 onosDPIDs.append(
3136 switch[ 'id' ].replace(
3137 ":",
Jon Halld80cc142015-07-06 13:36:05 -07003138 '' ).replace(
3139 "of",
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003140 '' ).lower() )
3141 onosDPIDs.sort()
Jon Hallafa8a472015-06-12 14:02:42 -07003142
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003143 if mnDPIDs != onosDPIDs:
3144 switchResults = main.FALSE
3145 main.log.error( "Switches in MN but not in ONOS:" )
3146 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
3147 main.log.error( str( list1 ) )
3148 main.log.error( "Switches in ONOS but not in MN:" )
3149 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
3150 main.log.error( str( list2 ) )
3151 else: # list of dpid's match in onos and mn
3152 switchResults = main.TRUE
3153 finalResults = switchResults
Jon Hall38481722014-11-04 16:50:05 -05003154
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003155 # FIXME: this does not look for extra ports in ONOS, only checks that
3156 # ONOS has what is in MN
3157 portsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07003158
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003159 # PORTS
3160 for name, mnSwitch in switches.iteritems():
3161 mnPorts = []
3162 onosPorts = []
3163 switchResult = main.TRUE
3164 for port in mnSwitch[ 'ports' ]:
3165 if port[ 'enabled' ]:
3166 mnPorts.append( int( port[ 'of_port' ] ) )
3167 for onosSwitch in portsJson:
3168 if onosSwitch[ 'device' ][ 'available' ]:
3169 if onosSwitch[ 'device' ][ 'id' ].replace(
3170 ':',
3171 '' ).replace(
3172 "of",
3173 '' ) == mnSwitch[ 'dpid' ]:
3174 for port in onosSwitch[ 'ports' ]:
3175 if port[ 'isEnabled' ]:
3176 if port[ 'port' ] == 'local':
3177 # onosPorts.append( 'local' )
3178 onosPorts.append( long( uint64( -2 ) ) )
3179 else:
3180 onosPorts.append( int( port[ 'port' ] ) )
3181 break
3182 mnPorts.sort( key=float )
3183 onosPorts.sort( key=float )
3184
3185 mnPortsLog = mnPorts
3186 onosPortsLog = onosPorts
3187 mnPorts = [ x for x in mnPorts ]
3188 onosPorts = [ x for x in onosPorts ]
3189
3190 # TODO: handle other reserved port numbers besides LOCAL
3191 # NOTE: Reserved ports
3192 # Local port: -2 in Openflow, ONOS shows 'local', we store as
3193 # long( uint64( -2 ) )
3194 for mnPort in mnPortsLog:
3195 if mnPort in onosPorts:
3196 # don't set results to true here as this is just one of
3197 # many checks and it might override a failure
3198 mnPorts.remove( mnPort )
3199 onosPorts.remove( mnPort )
3200
3201 # NOTE: OVS reports this as down since there is no link
3202 # So ignoring these for now
3203 # TODO: Come up with a better way of handling these
3204 if 65534 in mnPorts:
3205 mnPorts.remove( 65534 )
3206 if long( uint64( -2 ) ) in onosPorts:
3207 onosPorts.remove( long( uint64( -2 ) ) )
3208 if len( mnPorts ): # the ports of this switch don't match
3209 switchResult = main.FALSE
3210 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
3211 if len( onosPorts ): # the ports of this switch don't match
3212 switchResult = main.FALSE
3213 main.log.warn(
3214 "Ports in ONOS but not MN: " +
3215 str( onosPorts ) )
3216 if switchResult == main.FALSE:
3217 main.log.error(
3218 "The list of ports for switch %s(%s) does not match:" %
3219 ( name, mnSwitch[ 'dpid' ] ) )
3220 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
3221 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
3222 portsResults = portsResults and switchResult
3223 finalResults = finalResults and portsResults
3224 return finalResults
3225 except pexpect.EOF:
3226 main.log.error( self.name + ": EOF exception found" )
3227 main.log.error( self.name + ": " + self.handle.before )
3228 main.cleanup()
3229 main.exit()
3230 except Exception:
3231 main.log.exception( self.name + ": Uncaught exception!" )
3232 main.cleanup()
3233 main.exit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003234
Jon Hallafa8a472015-06-12 14:02:42 -07003235 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08003236 """
3237 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08003238 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04003239
Jon Hallafa8a472015-06-12 14:02:42 -07003240 """
Jon Hall7eb38402015-01-08 17:19:54 -08003241 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08003242 # ONOS has what is in MN
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003243 try:
3244 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04003245
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003246 mnLinks = []
3247 for l in links:
3248 try:
3249 node1 = switches[ l[ 'node1' ] ]
3250 node2 = switches[ l[ 'node2' ] ]
3251 enabled = True
3252 for port in node1[ 'ports' ]:
3253 if port[ 'of_port' ] == l[ 'port1' ]:
3254 enabled = enabled and port[ 'enabled' ]
3255 for port in node2[ 'ports' ]:
3256 if port[ 'of_port' ] == l[ 'port2' ]:
3257 enabled = enabled and port[ 'enabled' ]
3258 if enabled:
3259 mnLinks.append( l )
3260 except KeyError:
Jon Hall72cf1dc2014-10-20 21:04:50 -04003261 pass
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003262 if 2 * len( mnLinks ) == len( onos ):
3263 linkResults = main.TRUE
3264 else:
3265 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07003266 main.log.error(
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003267 "Mininet has " + str( len( mnLinks ) ) +
3268 " bidirectional links and ONOS has " +
3269 str( len( onos ) ) + " unidirectional links" )
3270
3271 # iterate through MN links and check if an ONOS link exists in
3272 # both directions
3273 for link in mnLinks:
3274 # TODO: Find a more efficient search method
3275 node1 = None
3276 port1 = None
3277 node2 = None
3278 port2 = None
3279 firstDir = main.FALSE
3280 secondDir = main.FALSE
3281 for swName, switch in switches.iteritems():
3282 if swName == link[ 'node1' ]:
3283 node1 = switch[ 'dpid' ]
3284 for port in switch[ 'ports' ]:
3285 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
3286 port1 = port[ 'of_port' ]
3287 if node1 is not None and node2 is not None:
3288 break
3289 if swName == link[ 'node2' ]:
3290 node2 = switch[ 'dpid' ]
3291 for port in switch[ 'ports' ]:
3292 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
3293 port2 = port[ 'of_port' ]
3294 if node1 is not None and node2 is not None:
3295 break
3296
3297 for onosLink in onos:
3298 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
3299 ":", '' ).replace( "of", '' )
3300 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
3301 ":", '' ).replace( "of", '' )
3302 onosPort1 = onosLink[ 'src' ][ 'port' ]
3303 onosPort2 = onosLink[ 'dst' ][ 'port' ]
3304
3305 # check onos link from node1 to node2
3306 if str( onosNode1 ) == str( node1 ) and str(
3307 onosNode2 ) == str( node2 ):
3308 if int( onosPort1 ) == int( port1 ) and int(
3309 onosPort2 ) == int( port2 ):
3310 firstDir = main.TRUE
3311 else:
3312 main.log.warn(
3313 'The port numbers do not match for ' +
3314 str( link ) +
3315 ' between ONOS and MN. When checking ONOS for ' +
3316 'link %s/%s -> %s/%s' %
3317 ( node1, port1, node2, port2 ) +
3318 ' ONOS has the values %s/%s -> %s/%s' %
3319 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
3320
3321 # check onos link from node2 to node1
3322 elif ( str( onosNode1 ) == str( node2 ) and
3323 str( onosNode2 ) == str( node1 ) ):
3324 if ( int( onosPort1 ) == int( port2 )
3325 and int( onosPort2 ) == int( port1 ) ):
3326 secondDir = main.TRUE
3327 else:
3328 main.log.warn(
3329 'The port numbers do not match for ' +
3330 str( link ) +
3331 ' between ONOS and MN. When checking ONOS for ' +
3332 'link %s/%s -> %s/%s' %
3333 ( node1, port1, node2, port2 ) +
3334 ' ONOS has the values %s/%s -> %s/%s' %
3335 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
3336 else: # this is not the link you're looking for
3337 pass
3338 if not firstDir:
3339 main.log.error(
3340 'ONOS does not have the link %s/%s -> %s/%s' %
3341 ( node1, port1, node2, port2 ) )
3342 if not secondDir:
3343 main.log.error(
3344 'ONOS does not have the link %s/%s -> %s/%s' %
3345 ( node2, port2, node1, port1 ) )
3346 linkResults = linkResults and firstDir and secondDir
3347 return linkResults
3348 except pexpect.EOF:
3349 main.log.error( self.name + ": EOF exception found" )
3350 main.log.error( self.name + ": " + self.handle.before )
3351 main.cleanup()
3352 main.exit()
3353 except Exception:
3354 main.log.exception( self.name + ": Uncaught exception!" )
3355 main.cleanup()
3356 main.exit()
Jon Hall72cf1dc2014-10-20 21:04:50 -04003357
Jon Hallafa8a472015-06-12 14:02:42 -07003358 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08003359 """
Jon Hallafa8a472015-06-12 14:02:42 -07003360 Compare mn and onos Hosts.
3361 Since Mininet hosts are quiet, ONOS will only know of them when they
3362 speak. For this reason, we will only check that the hosts in ONOS
3363 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08003364
Jon Hallafa8a472015-06-12 14:02:42 -07003365 Arguments:
3366 hostsJson: parsed json object from the onos hosts api
3367 Returns:
3368 """
Jon Hallff6b4b22015-02-23 09:25:15 -08003369 import json
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003370 try:
3371 hostResults = main.TRUE
3372 for onosHost in hostsJson:
3373 onosMAC = onosHost[ 'mac' ].lower()
3374 match = False
3375 for mnHost, info in hosts.iteritems():
3376 for mnIntf in info[ 'interfaces' ]:
3377 if onosMAC == mnIntf[ 'mac' ].lower():
3378 match = True
3379 for ip in mnIntf[ 'ips' ]:
3380 if ip in onosHost[ 'ipAddresses' ]:
3381 pass # all is well
3382 else:
3383 # misssing ip
3384 main.log.error( "ONOS host " +
3385 onosHost[ 'id' ] +
3386 " has a different IP(" +
3387 str( onosHost[ 'ipAddresses' ] ) +
3388 ") than the Mininet host(" +
3389 str( ip ) +
3390 ")." )
3391 output = json.dumps(
3392 onosHost,
3393 sort_keys=True,
3394 indent=4,
3395 separators=( ',', ': ' ) )
3396 main.log.info( output )
3397 hostResults = main.FALSE
3398 if not match:
3399 hostResults = main.FALSE
3400 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
3401 "corresponding Mininet host." )
3402 output = json.dumps( onosHost,
3403 sort_keys=True,
3404 indent=4,
3405 separators=( ',', ': ' ) )
3406 main.log.info( output )
3407 return hostResults
3408 except pexpect.EOF:
3409 main.log.error(self.name + ": EOF exception found")
3410 main.log.error(self.name + ": " + self.handle.before)
3411 main.cleanup()
3412 main.exit()
3413 except Exception:
3414 main.log.exception(self.name + ": Uncaught exception!")
3415 main.cleanup()
3416 main.exit()
Jon Hallff6b4b22015-02-23 09:25:15 -08003417
Jon Hallafa8a472015-06-12 14:02:42 -07003418 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08003419 """
3420 Returns a list of all hosts
3421 Don't ask questions just use it"""
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003422 try:
3423 self.handle.sendline( "" )
3424 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04003425
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003426 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
3427 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003428
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003429 handlePy = self.handle.before
3430 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3431 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07003432
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003433 self.handle.sendline( "" )
3434 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07003435
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003436 hostStr = handlePy.replace( "]", "" )
3437 hostStr = hostStr.replace( "'", "" )
3438 hostStr = hostStr.replace( "[", "" )
3439 hostStr = hostStr.replace( " ", "" )
3440 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04003441
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003442 return hostList
3443 except pexpect.TIMEOUT:
3444 main.log.error(self.name + ": TIMEOUT exception found")
3445 main.log.error(self.name + ": " + self.handle.before)
3446 main.cleanup()
3447 main.exit()
3448 except pexpect.EOF:
3449 main.log.error( self.name + ": EOF exception found" )
3450 main.log.error( self.name + ": " + self.handle.before )
3451 main.cleanup()
3452 main.exit()
3453 except Exception:
3454 main.log.exception( self.name + ": Uncaught exception!" )
3455 main.cleanup()
3456 main.exit()
adminbae64d82013-08-01 10:50:15 -07003457
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003458 def getSwitch( self ):
3459 """
3460 Returns a list of all switches
3461 Again, don't ask question just use it...
3462 """
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003463 try:
3464 # get host list...
3465 hostList = self.getHosts()
3466 # Make host set
3467 hostSet = set( hostList )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003468
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003469 # Getting all the nodes in mininet
3470 self.handle.sendline( "" )
3471 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003472
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003473 self.handle.sendline( "py [ node.name for node in net.values() ]" )
3474 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003475
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003476 handlePy = self.handle.before
3477 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
3478 handlePy = handlePy.rstrip()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003479
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003480 self.handle.sendline( "" )
3481 self.handle.expect( "mininet>" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003482
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003483 nodesStr = handlePy.replace( "]", "" )
3484 nodesStr = nodesStr.replace( "'", "" )
3485 nodesStr = nodesStr.replace( "[", "" )
3486 nodesStr = nodesStr.replace( " ", "" )
3487 nodesList = nodesStr.split( "," )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003488
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003489 nodesSet = set( nodesList )
3490 # discarding default controller(s) node
3491 nodesSet.discard( 'c0' )
3492 nodesSet.discard( 'c1' )
3493 nodesSet.discard( 'c2' )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003494
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003495 switchSet = nodesSet - hostSet
3496 switchList = list( switchSet )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003497
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003498 return switchList
3499 except pexpect.TIMEOUT:
3500 main.log.error(self.name + ": TIMEOUT exception found")
3501 main.log.error(self.name + ": " + self.handle.before)
3502 main.cleanup()
3503 main.exit()
3504 except pexpect.EOF:
3505 main.log.error( self.name + ": EOF exception found" )
3506 main.log.error( self.name + ": " + self.handle.before )
3507 main.cleanup()
3508 main.exit()
3509 except Exception:
3510 main.log.exception( self.name + ": Uncaught exception!" )
3511 main.cleanup()
3512 main.exit()
kelvin-onlabfa6ada82015-06-11 13:06:24 -07003513
You Wangdb8cd0a2016-05-26 15:19:45 -07003514 def getGraphDict( self, timeout=60, useId=True, includeHost=False ):
3515 """
3516 Return a dictionary which describes the latest Mininet topology data as a
3517 graph.
3518 An example of the dictionary:
3519 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
3520 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
3521 Each vertex should at least have an 'edges' attribute which describes the
3522 adjacency information. The value of 'edges' attribute is also represented by
3523 a dictionary, which maps each edge (identified by the neighbor vertex) to a
3524 list of attributes.
3525 An example of the edges dictionary:
3526 'edges': { vertex2: { 'port': ..., 'weight': ... },
3527 vertex3: { 'port': ..., 'weight': ... } }
3528 If useId == True, dpid/mac will be used instead of names to identify
3529 vertices, which is helpful when e.g. comparing Mininet topology with ONOS
3530 topology.
3531 If includeHost == True, all hosts (and host-switch links) will be included
3532 in topology data.
3533 Note that link or switch that are brought down by 'link x x down' or 'switch
3534 x down' commands still show in the output of Mininet CLI commands such as
3535 'links', 'dump', etc. Thus, to ensure the correctness of this function, it is
3536 recommended to use delLink() or delSwitch functions to simulate link/switch
3537 down, and addLink() or addSwitch to add them back.
3538 """
3539 graphDict = {}
3540 try:
3541 links = self.getLinks( timeout=timeout )
3542 portDict = {}
3543 if useId:
3544 switches = self.getSwitches()
3545 if includeHost:
3546 hosts = self.getHosts()
3547 for link in links:
3548 # FIXME: support 'includeHost' argument
3549 if link[ 'node1' ].startswith( 'h' ) or link[ 'node2' ].startswith( 'h' ):
3550 continue
3551 nodeName1 = link[ 'node1' ]
3552 nodeName2 = link[ 'node2' ]
3553 port1 = link[ 'port1' ]
3554 port2 = link[ 'port2' ]
3555 # Loop for two nodes
3556 for i in range( 2 ):
3557 # Get port index from OVS
3558 # The index extracted from port name may be inconsistent with ONOS
3559 portIndex = -1
3560 if not nodeName1 in portDict.keys():
3561 portList = self.getOVSPorts( nodeName1 )
3562 if len( portList ) == 0:
3563 main.log.warn( self.name + ": No port found on switch " + nodeName1 )
3564 return None
3565 portDict[ nodeName1 ] = portList
3566 for port in portDict[ nodeName1 ]:
3567 if port[ 'port' ] == port1:
3568 portIndex = port[ 'index' ]
3569 break
3570 if portIndex == -1:
3571 main.log.warn( self.name + ": Cannot find port index for interface {}-eth{}".format( nodeName1, port1 ) )
3572 return None
3573 if useId:
3574 node1 = 'of:' + str( switches[ nodeName1 ][ 'dpid' ] )
3575 node2 = 'of:' + str( switches[ nodeName2 ][ 'dpid' ] )
3576 else:
3577 node1 = nodeName1
3578 node2 = nodeName2
3579 if not node1 in graphDict.keys():
3580 if useId:
3581 graphDict[ node1 ] = { 'edges':{},
3582 'dpid':switches[ nodeName1 ][ 'dpid' ],
3583 'name':nodeName1,
3584 'ports':switches[ nodeName1 ][ 'ports' ],
3585 'swClass':switches[ nodeName1 ][ 'swClass' ],
3586 'pid':switches[ nodeName1 ][ 'pid' ],
3587 'options':switches[ nodeName1 ][ 'options' ] }
3588 else:
3589 graphDict[ node1 ] = { 'edges':{} }
3590 else:
3591 # Assert node2 is not connected to any current links of node1
3592 assert node2 not in graphDict[ node1 ][ 'edges' ].keys()
3593 graphDict[ node1 ][ 'edges' ][ node2 ] = { 'port':portIndex }
3594 # Swap two nodes/ports
3595 nodeName1, nodeName2 = nodeName2, nodeName1
3596 port1, port2 = port2, port1
3597 return graphDict
3598 except KeyError:
3599 main.log.exception( self.name + ": KeyError exception found" )
3600 return None
3601 except AssertionError:
3602 main.log.exception( self.name + ": AssertionError exception found" )
3603 return None
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003604 except pexpect.EOF:
3605 main.log.error( self.name + ": EOF exception found" )
3606 main.log.error( self.name + ": " + self.handle.before )
3607 main.cleanup()
3608 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07003609 except Exception:
3610 main.log.exception( self.name + ": Uncaught exception" )
3611 return None
3612
Jon Hall7eb38402015-01-08 17:19:54 -08003613 def update( self ):
3614 """
3615 updates the port address and status information for
3616 each port in mn"""
3617 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08003618 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05003619 try:
Jon Hall7eb38402015-01-08 17:19:54 -08003620 self.handle.sendline( "" )
3621 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003622
Jon Hall7eb38402015-01-08 17:19:54 -08003623 self.handle.sendline( "update" )
3624 self.handle.expect( "update" )
3625 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003626
Jon Hall7eb38402015-01-08 17:19:54 -08003627 self.handle.sendline( "" )
3628 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05003629
Jon Hallb1290e82014-11-18 16:17:48 -05003630 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003631 except pexpect.TIMEOUT:
3632 main.log.error(self.name + ": TIMEOUT exception found")
3633 main.log.error(self.name + ": " + self.handle.before)
3634 main.cleanup()
3635 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05003636 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08003637 main.log.error( self.name + ": EOF exception found" )
3638 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05003639 main.cleanup()
3640 main.exit()
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003641 except Exception:
3642 main.log.exception( self.name + ": Uncaught exception!" )
3643 main.cleanup()
3644 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -05003645
Jon Halld80cc142015-07-06 13:36:05 -07003646 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07003647 """
3648 Add vlan tag to a host.
3649 Dependencies:
3650 This class depends on the "vlan" package
3651 $ sudo apt-get install vlan
3652 Configuration:
3653 Load the 8021q module into the kernel
3654 $sudo modprobe 8021q
3655
3656 To make this setup permanent:
3657 $ sudo su -c 'echo "8021q" >> /etc/modules'
3658 """
3659 if self.handle:
3660 try:
Jon Halld80cc142015-07-06 13:36:05 -07003661 # get the ip address of the host
3662 main.log.info( "Get the ip address of the host" )
3663 ipaddr = self.getIPAddress( host )
3664 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07003665
Jon Halld80cc142015-07-06 13:36:05 -07003666 # remove IP from interface intf
3667 # Ex: h1 ifconfig h1-eth0 inet 0
3668 main.log.info( "Remove IP from interface " )
3669 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
3670 self.handle.sendline( cmd2 )
3671 self.handle.expect( "mininet>" )
3672 response = self.handle.before
3673 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003674
Jon Halld80cc142015-07-06 13:36:05 -07003675 # create VLAN interface
3676 # Ex: h1 vconfig add h1-eth0 100
3677 main.log.info( "Create Vlan" )
3678 cmd3 = host + " vconfig add " + intf + " " + vlan
3679 self.handle.sendline( cmd3 )
3680 self.handle.expect( "mininet>" )
3681 response = self.handle.before
3682 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003683
Jon Halld80cc142015-07-06 13:36:05 -07003684 # assign the host's IP to the VLAN interface
3685 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
3686 main.log.info( "Assign the host IP to the vlan interface" )
3687 vintf = intf + "." + vlan
3688 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
3689 self.handle.sendline( cmd4 )
3690 self.handle.expect( "mininet>" )
3691 response = self.handle.before
3692 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07003693
3694 return main.TRUE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003695 except pexpect.TIMEOUT:
3696 main.log.error(self.name + ": TIMEOUT exception found")
3697 main.log.error(self.name + ": " + self.handle.before)
3698 main.cleanup()
3699 main.exit()
kaouthera3f13ca22015-05-05 15:01:41 -07003700 except pexpect.EOF:
3701 main.log.error( self.name + ": EOF exception found" )
3702 main.log.error( self.name + ": " + self.handle.before )
3703 return main.FALSE
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003704 except Exception:
3705 main.log.exception( self.name + ": Uncaught exception!" )
3706 return main.FALSE
kaouthera3f13ca22015-05-05 15:01:41 -07003707
Jon Hall892818c2015-10-20 17:58:34 -07003708 def createHostComponent( self, name ):
3709 """
3710 Creates a new mininet cli component with the same parameters as self.
3711 This new component is intended to be used to login to the hosts created
3712 by mininet.
3713
3714 Arguments:
3715 name - The string of the name of this component. The new component
3716 will be assigned to main.<name> .
3717 In addition, main.<name>.name = str( name )
3718 """
3719 try:
3720 # look to see if this component already exists
3721 getattr( main, name )
3722 except AttributeError:
3723 # namespace is clear, creating component
3724 main.componentDictionary[name] = main.componentDictionary[self.name].copy()
3725 main.componentDictionary[name]['connect_order'] = str( int( main.componentDictionary[name]['connect_order'] ) + 1 )
3726 main.componentInit( name )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003727 except pexpect.EOF:
3728 main.log.error( self.name + ": EOF exception found" )
3729 main.log.error( self.name + ": " + self.handle.before )
3730 main.cleanup()
3731 main.exit()
Jon Hall892818c2015-10-20 17:58:34 -07003732 except Exception:
3733 main.log.exception( self.name + ": Uncaught exception!" )
3734 main.cleanup()
3735 main.exit()
3736 else:
3737 # namespace is not clear!
3738 main.log.error( name + " component already exists!" )
3739 # FIXME: Should we exit here?
3740 main.cleanup()
3741 main.exit()
3742
3743 def removeHostComponent( self, name ):
3744 """
3745 Remove host component
3746 Arguments:
3747 name - The string of the name of the component to delete.
3748 """
3749 try:
3750 # Get host component
3751 component = getattr( main, name )
3752 except AttributeError:
3753 main.log.error( "Component " + name + " does not exist." )
3754 return
3755 try:
3756 # Disconnect from component
3757 component.disconnect()
3758 # Delete component
3759 delattr( main, name )
3760 # Delete component from ComponentDictionary
3761 del( main.componentDictionary[name] )
Ming Yan Shu404f7e72016-07-22 14:37:03 -07003762 except pexpect.EOF:
3763 main.log.error( self.name + ": EOF exception found" )
3764 main.log.error( self.name + ": " + self.handle.before )
3765 main.cleanup()
3766 main.exit()
Jon Hall892818c2015-10-20 17:58:34 -07003767 except Exception:
3768 main.log.exception( self.name + ": Uncaught exception!" )
3769 main.cleanup()
3770 main.exit()
3771
3772 def startHostCli( self, host=None ):
3773 """
3774 Use the mininet m utility to connect to the host's cli
3775 """
3776 # These are fields that can be used by scapy packets. Initialized to None
3777 self.hostIp = None
3778 self.hostMac = None
3779 try:
3780 if not host:
3781 host = self.name
3782 self.handle.sendline( self.home + "/util/m " + host )
3783 self.handle.expect( self.hostPrompt )
3784 return main.TRUE
3785 except pexpect.TIMEOUT:
3786 main.log.exception( self.name + ": Command timed out" )
3787 return main.FALSE
3788 except pexpect.EOF:
3789 main.log.exception( self.name + ": connection closed." )
3790 main.cleanup()
3791 main.exit()
3792 except Exception:
3793 main.log.exception( self.name + ": Uncaught exception!" )
3794 main.cleanup()
3795 main.exit()
3796
Jon Hall892818c2015-10-20 17:58:34 -07003797
adminbae64d82013-08-01 10:50:15 -07003798if __name__ != "__main__":
kelvin-onlab50907142015-04-01 13:37:45 -07003799 sys.modules[ __name__ ] = MininetCliDriver()