blob: 89a2611edcad3865f3014bd35ab7c55868e4519a [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
Jon Hallbe6dfc42015-01-12 17:37:25 -080021MininetCliDriver is the basic driver which will handle the Mininet functions
22
23Some functions rely on a modified version of Mininet. These functions
24should all be noted in the comments. To get this MN version run these commands
25from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080026 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080027 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080028 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git pull
30
Jon Hall272a4db2015-01-12 17:43:48 -080031
32 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080033changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070034import pexpect
adminbae64d82013-08-01 10:50:15 -070035import re
36import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070037import types
kelvin-onlaba4074292015-07-09 15:19:49 -070038import os
Jon Hall1ccf82c2014-10-15 14:55:16 -040039from math import pow
adminbae64d82013-08-01 10:50:15 -070040from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070041
Jon Hall7eb38402015-01-08 17:19:54 -080042
kelvin-onlab50907142015-04-01 13:37:45 -070043class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080044
45 """
46 MininetCliDriver is the basic driver which will handle
47 the Mininet functions"""
48 def __init__( self ):
49 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070050 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080051 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070052 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080053 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070054 self.flag = 0
55
Jon Hall7eb38402015-01-08 17:19:54 -080056 def connect( self, **connectargs ):
57 """
58 Here the main is the TestON instance after creating
59 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080060 try:
61 for key in connectargs:
62 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070063 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080064 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070065 for key in self.options:
66 if key == "home":
67 self.home = self.options[ 'home' ]
68 break
69 if self.home is None or self.home == "":
70 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070071
72 try:
73 if os.getenv( str( self.ip_address ) ) != None:
74 self.ip_address = os.getenv( str( self.ip_address ) )
75 else:
76 main.log.info( self.name +
77 ": Trying to connect to " +
78 self.ip_address )
79
80 except KeyError:
81 main.log.info( "Invalid host name," +
82 " connecting to local host instead" )
83 self.ip_address = 'localhost'
84 except Exception as inst:
85 main.log.error( "Uncaught exception: " + str( inst ) )
86
kelvin-onlaba1484582015-02-02 15:46:20 -080087 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070088 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080089 self ).connect(
90 user_name=self.user_name,
91 ip_address=self.ip_address,
92 port=None,
93 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080094
kelvin-onlaba1484582015-02-02 15:46:20 -080095 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080096 main.log.info( "Connection successful to the host " +
97 self.user_name +
98 "@" +
99 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800100 return main.TRUE
101 else:
102 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800103 self.user_name +
104 "@" +
105 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800106 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800107 return main.FALSE
108 except pexpect.EOF:
109 main.log.error( self.name + ": EOF exception found" )
110 main.log.error( self.name + ": " + self.handle.before )
111 main.cleanup()
112 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800113 except Exception:
114 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800115 main.cleanup()
116 main.exit()
117
kelvin-onlab10e8d392015-06-03 13:53:45 -0700118 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800119 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700120 Description:
121 Starts Mininet accepts a topology(.py) file and/or an optional
122 argument, to start the mininet, as a parameter.
123 Can also send regular mininet command to load up desired topology.
124 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
125 Options:
126 topoFile = file path for topology file (.py)
127 args = extra option added when starting the topology from the file
128 mnCmd = Mininet command use to start topology
129 Returns:
130 main.TRUE if the mininet starts successfully, main.FALSE
131 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800132 """
Jon Hall7eb38402015-01-08 17:19:54 -0800133 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700134 # make sure old networks are cleaned up
135 main.log.info( self.name +
136 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800137 self.handle.sendline( "sudo mn -c" )
138 i = self.handle.expect( [ 'password\sfor\s',
139 'Cleanup\scomplete',
140 pexpect.EOF,
141 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800142 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800143 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700144 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800145 main.log.info( self.name + ": Sending sudo password" )
146 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800147 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800148 '\$',
149 pexpect.EOF,
150 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800151 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800152 if i == 1:
153 main.log.info( self.name + ": Clean" )
154 elif i == 2:
155 main.log.error( self.name + ": Connection terminated" )
156 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700157 main.log.error( self.name + ": Something while cleaning " +
158 "Mininet took too long... " )
159 # Craft the string to start mininet
160 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700161 if not mnCmd:
162 if topoFile is None or topoFile == '': # If no file is given
163 main.log.info( self.name + ": building fresh Mininet" )
164 cmdString += "mn "
165 if args is None or args == '':
166 # If no args given, use args from .topo file
167 args = self.options[ 'arg1' ] +\
Jon Halld80cc142015-07-06 13:36:05 -0700168 " " + self.options[ 'arg2' ] +\
169 " --mac --controller " +\
170 self.options[ 'controller' ] + " " +\
171 self.options[ 'arg3' ]
kelvin-onlab10e8d392015-06-03 13:53:45 -0700172 else: # else only use given args
173 pass
174 # TODO: allow use of topo args and method args?
175 else: # Use given topology file
Jon Halld80cc142015-07-06 13:36:05 -0700176 main.log.info(
177 "Starting Mininet from topo file " +
178 topoFile )
kelvin-onlab10e8d392015-06-03 13:53:45 -0700179 cmdString += topoFile + " "
180 if args is None:
181 args = ''
182 # TODO: allow use of args from .topo file?
183 cmdString += args
184 else:
185 main.log.info( "Starting Mininet topology using '" + mnCmd +
186 "' command" )
187 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700188 # Send the command and check if network started
189 self.handle.sendline( "" )
190 self.handle.expect( '\$' )
191 main.log.info( "Sending '" + cmdString + "' to " + self.name )
192 self.handle.sendline( cmdString )
193 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800194 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700195 'Exception',
196 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800197 pexpect.EOF,
198 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700199 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800200 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700201 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800202 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800203 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700204 response = str( self.handle.before +
205 self.handle.after )
206 self.handle.expect( '\$' )
207 response += str( self.handle.before +
Jon Halld80cc142015-07-06 13:36:05 -0700208 self.handle.after )
Jon Hall689d8e42015-04-03 13:59:24 -0700209 main.log.error(
210 self.name +
211 ": Launching Mininet failed: " + response )
212 return main.FALSE
213 elif i == 2:
214 self.handle.expect( [ "\n",
215 pexpect.EOF,
216 pexpect.TIMEOUT ],
217 timeout )
218 main.log.info( self.handle.before )
219 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800220 main.log.error( self.name + ": Connection timeout" )
221 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700222 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800223 main.log.error(
224 self.name +
225 ": Something took too long... " )
226 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700227 # Why did we hit this part?
228 main.log.error( "startNet did not return correctly" )
229 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800230 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700231 main.log.error( self.name + ": Connection failed to the host " +
232 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800233 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700234 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800235
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800236 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400237 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800238 # In tree topology, if fanout arg is not given, by default it is 2
239 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400240 fanout = 2
241 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500242 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800243 while( k <= depth - 1 ):
244 count = count + pow( fanout, k )
245 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800247 while( k <= depth - 2 ):
248 # depth-2 gives you only core links and not considering
249 # edge links as seen by ONOS. If all the links including
250 # edge links are required, do depth-1
251 count = count + pow( fanout, k )
252 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800254 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800256
Jon Hall7eb38402015-01-08 17:19:54 -0800257 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800259 # by default it is 1
260 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400261 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 numSwitches = depth
263 numHostsPerSw = fanout
264 totalNumHosts = numSwitches * numHostsPerSw
265 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800266 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800268 topoDict = { "num_switches": int( numSwitches ),
269 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400270 return topoDict
271
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700273 """
274 Calculate the number of switches and links in a topo."""
275 # TODO: combine this function and numSwitchesNlinks
276 argList = self.options[ 'arg1' ].split( "," )
277 topoArgList = argList[ 0 ].split( " " )
278 argList = map( int, argList[ 1: ] )
279 topoArgList = topoArgList[ 1: ] + argList
280
281 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400282 return topoDict
283
Jon Halld80cc142015-07-06 13:36:05 -0700284 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800285 """
286 Verifies the reachability of the hosts using pingall command.
287 Optional parameter timeout allows you to specify how long to
288 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700289 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700290 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700291 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700292 ping
293 acceptableFailed - Set the number of acceptable failed pings for the
294 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800295 Returns:
296 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700297 otherwise main.FALSE
298 """
299 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700300 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700301 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700302 if self.handle:
303 main.log.info(
304 self.name +
305 ": Checking reachabilty to the hosts using pingall" )
306 response = ""
307 failedPings = 0
308 returnValue = main.TRUE
309 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700310 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700311 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700312 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700313 pexpect.EOF,
314 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700315 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700316 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700317 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700318 response += self.handle.before
319 break
320 elif i == 1:
321 response += self.handle.before + self.handle.after
322 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700323 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700324 returnValue = main.FALSE
325 if shortCircuit:
326 main.log.error( self.name +
327 ": Aborting pingall - "
328 + str( failedPings ) +
329 " pings failed" )
330 break
Jon Hall390696c2015-05-05 17:13:41 -0700331 if ( time.time() - startTime ) > timeout:
332 returnValue = main.FALSE
333 main.log.error( self.name +
334 ": Aborting pingall - " +
335 "Function took too long " )
336 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700337 elif i == 2:
338 main.log.error( self.name +
339 ": EOF exception found" )
340 main.log.error( self.name + ": " +
341 self.handle.before )
342 main.cleanup()
343 main.exit()
344 elif i == 3:
345 response += self.handle.before
346 main.log.error( self.name +
347 ": TIMEOUT exception found" )
348 main.log.error( self.name +
349 ": " +
350 str( response ) )
351 # NOTE: Send ctrl-c to make sure pingall is done
352 self.handle.sendline( "\x03" )
353 self.handle.expect( "Interrupt" )
354 self.handle.expect( "mininet>" )
355 break
356 pattern = "Results\:"
357 main.log.info( "Pingall output: " + str( response ) )
358 if re.search( pattern, response ):
359 main.log.info( self.name + ": Pingall finished with "
360 + str( failedPings ) + " failed pings" )
361 return returnValue
362 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700363 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700364 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700365 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700366 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700367 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700368 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700369 main.log.error( self.name + ": Connection failed to the host" )
370 main.cleanup()
371 main.exit()
372 except pexpect.TIMEOUT:
373 if response:
374 main.log.info( "Pingall output: " + str( response ) )
375 main.log.error( self.name + ": pexpect.TIMEOUT found" )
376 return main.FALSE
377 except pexpect.EOF:
378 main.log.error( self.name + ": EOF exception found" )
379 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500380 main.cleanup()
381 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700382
Jon Hall7eb38402015-01-08 17:19:54 -0800383 def fpingHost( self, **pingParams ):
384 """
385 Uses the fping package for faster pinging...
386 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800387 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800388 command = args[ "SRC" ] + \
389 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
390 self.handle.sendline( command )
391 self.handle.expect(
392 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
393 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
394 response = self.handle.before
395 if re.search( ":\s-", response ):
396 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700397 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800398 elif re.search( ":\s\d{1,2}\.\d\d", response ):
399 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700400 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800401 main.log.info( self.name + ": Install fping on mininet machine... " )
402 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700403 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800404
Hari Krishna9592fc82015-07-31 15:11:15 -0700405 def pingallHosts( self, hostList ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700407 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700408
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400409 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700410 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700411
412 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400413 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700414
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400415 Returns main.FALSE if one or more of hosts specified
416 cannot reach each other"""
Hari Krishna9592fc82015-07-31 15:11:15 -0700417
418 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400419
420 try:
421 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700422
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400423 isReachable = main.TRUE
424
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400425 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700426 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400427 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700428 pingList = hostList[ :listIndex ] + \
429 hostList[ ( listIndex + 1 ): ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700430
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400431 for temp in pingList:
432 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700433 pingCmd = str( host ) + cmd + str( temp )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400434 self.handle.sendline( pingCmd )
435 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
436 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
437 response = self.handle.before
438 if re.search( ',\s0\%\spacket\sloss', response ):
Jon Halld80cc142015-07-06 13:36:05 -0700439 main.log.info( str( host ) + " -> " + str( temp ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400440 else:
Jon Halld80cc142015-07-06 13:36:05 -0700441 main.log.info(
442 str( host ) + " -> X (" + str( temp ) + ") "
443 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400444 # One of the host to host pair is unreachable
445 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400446
kelvin-onlab2ff57022015-05-29 10:48:51 -0700447 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400448
449 except pexpect.EOF:
450 main.log.error( self.name + ": EOF exception found" )
451 main.log.error( self.name + ": " + self.handle.before )
452 main.cleanup()
453 main.exit()
454
kelvin-onlab9b42b0a2015-08-05 14:43:58 -0700455 def pingIpv6Hosts(self, hostList, prefix='1000::'):
Hari Krishna9592fc82015-07-31 15:11:15 -0700456 """
457 IPv6 ping all hosts in hostList. If no prefix passed this will use
458 default prefix of 1000::
459
460 Returns main.TRUE if all hosts specified can reach each other
461
462 Returns main.FALSE if one or more of hosts specified cannot reach each other
463 """
464 try:
465 main.log.info( "Testing reachability between specified IPv6 hosts" )
466 isReachable = main.TRUE
467 cmd = " ping6 -c 1 -i 1 -W 8 "
468 for host in hostList:
469 listIndex = hostList.index( host )
470 # List of hosts to ping other than itself
471 pingList = hostList[ :listIndex ] + \
472 hostList[ ( listIndex + 1 ): ]
473
474 for temp in pingList:
475 # Current host pings all other hosts specified
476 pingCmd = str( host ) + cmd + prefix + str( temp[1:] )
477 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
478 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
479 response = self.handle.before
480 if re.search( ',\s0\%\spacket\sloss', response ):
481 main.log.info( str( host ) + " -> " + str( temp ) )
482 else:
483 main.log.info(
484 str( host ) + " -> X (" + str( temp ) + ") "
485 " Destination Unreachable" )
486 main.log.error( "Response from Mininet: " + str( response ) )
487 # One of the host to host pair is unreachable
488 isReachable = main.FALSE
489 return isReachable
490
491 except pexpect.EOF:
492 main.log.error( self.name + ": EOF exception found" )
493 main.log.error( self.name + ": " + self.handle.before )
494 main.cleanup()
495 main.exit()
496
Jon Hall7eb38402015-01-08 17:19:54 -0800497 def pingHost( self, **pingParams ):
498 """
499 Ping from one mininet host to another
500 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800501 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800502 command = args[ "SRC" ] + " ping " + \
503 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700504 try:
Jon Hall61282e32015-03-19 11:34:11 -0700505 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800506 self.handle.sendline( command )
507 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700508 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800509 main.log.error(
510 self.name +
511 ": timeout when waiting for response from mininet" )
512 main.log.error( "response: " + str( self.handle.before ) )
513 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700514 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800515 main.log.error(
516 self.name +
517 ": timeout when waiting for response from mininet" )
518 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700519 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800520 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800521 main.log.error( self.name + ": EOF exception found" )
522 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700523 main.cleanup()
524 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800525 main.log.info( self.name + ": Ping Response: " + response )
526 if re.search( ',\s0\%\spacket\sloss', response ):
527 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800528 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700529 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800530 else:
531 main.log.error(
532 self.name +
533 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800534 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700535 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800536
Jon Hall7eb38402015-01-08 17:19:54 -0800537 def checkIP( self, host ):
538 """
539 Verifies the host's ip configured or not."""
540 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700541 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800542 response = self.execute(
543 cmd=host +
544 " ifconfig",
545 prompt="mininet>",
546 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800547 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800548 main.log.error( self.name + ": EOF exception found" )
549 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700550 main.cleanup()
551 main.exit()
adminbae64d82013-08-01 10:50:15 -0700552
Jon Hall7eb38402015-01-08 17:19:54 -0800553 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800554 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
555 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
556 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
557 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
558 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800559 # pattern = "inet addr:10.0.0.6"
560 if re.search( pattern, response ):
561 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700562 return main.TRUE
563 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800564 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700565 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800566 else:
567 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800568
Jon Hall7eb38402015-01-08 17:19:54 -0800569 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800570 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700571 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800572 response = self.execute(
573 cmd="h1 /usr/sbin/sshd -D&",
574 prompt="mininet>",
575 timeout=10 )
576 response = self.execute(
577 cmd="h4 /usr/sbin/sshd -D&",
578 prompt="mininet>",
579 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700580 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800581 vars( self )[ key ] = connectargs[ key ]
582 response = self.execute(
583 cmd="xterm h1 h4 ",
584 prompt="mininet>",
585 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800586 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800587 main.log.error( self.name + ": EOF exception found" )
588 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700589 main.cleanup()
590 main.exit()
adminbae64d82013-08-01 10:50:15 -0700591 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800592 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700593 if self.flag == 0:
594 self.flag = 1
595 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800596 else:
adminbae64d82013-08-01 10:50:15 -0700597 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800598
kelvin-onlaba1484582015-02-02 15:46:20 -0800599 def moveHost( self, host, oldSw, newSw, ):
600 """
601 Moves a host from one switch to another on the fly
602 Note: The intf between host and oldSw when detached
603 using detach(), will still show up in the 'net'
604 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700605 ( which is correct behavior since the interfaces
606 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800607 """
608 if self.handle:
609 try:
610 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700611 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800612 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800613 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800614 response = self.execute( cmd=cmd,
615 prompt="mininet>",
616 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700617
kelvin-onlaba1484582015-02-02 15:46:20 -0800618 # Determine hostintf and Oldswitchintf
619 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800620 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800621 print "cmd2= ", cmd
622 self.handle.sendline( cmd )
623 self.handle.expect( "mininet>" )
624
shahshreya73537862015-02-11 15:15:24 -0800625 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800626 cmd = "px ipaddr = hintf.IP()"
627 print "cmd3= ", cmd
628 self.handle.sendline( cmd )
629 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800630
631 cmd = "px macaddr = hintf.MAC()"
632 print "cmd3= ", cmd
633 self.handle.sendline( cmd )
634 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700635
kelvin-onlaba1484582015-02-02 15:46:20 -0800636 # Detach interface between oldSw-host
637 cmd = "px " + oldSw + ".detach( sintf )"
638 print "cmd4= ", cmd
639 self.handle.sendline( cmd )
640 self.handle.expect( "mininet>" )
641
642 # Add link between host-newSw
643 cmd = "py net.addLink(" + host + "," + newSw + ")"
644 print "cmd5= ", cmd
645 self.handle.sendline( cmd )
646 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700647
kelvin-onlaba1484582015-02-02 15:46:20 -0800648 # Determine hostintf and Newswitchintf
649 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800650 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800651 print "cmd6= ", cmd
652 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700653 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800654
655 # Attach interface between newSw-host
656 cmd = "px " + newSw + ".attach( sintf )"
657 print "cmd3= ", cmd
658 self.handle.sendline( cmd )
659 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700660
kelvin-onlaba1484582015-02-02 15:46:20 -0800661 # Set ipaddress of the host-newSw interface
662 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
663 print "cmd7 = ", cmd
664 self.handle.sendline( cmd )
665 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800666
667 # Set macaddress of the host-newSw interface
668 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
669 print "cmd8 = ", cmd
670 self.handle.sendline( cmd )
671 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700672
kelvin-onlaba1484582015-02-02 15:46:20 -0800673 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800674 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800675 self.handle.sendline( cmd )
676 self.handle.expect( "mininet>" )
677 print "output = ", self.handle.before
678
679 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800680 cmd = host + " ifconfig"
681 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800682 self.handle.sendline( cmd )
683 self.handle.expect( "mininet>" )
684 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700685
kelvin-onlaba1484582015-02-02 15:46:20 -0800686 return main.TRUE
687 except pexpect.EOF:
688 main.log.error( self.name + ": EOF exception found" )
689 main.log.error( self.name + ": " + self.handle.before )
690 return main.FALSE
691
Jon Hall7eb38402015-01-08 17:19:54 -0800692 def changeIP( self, host, intf, newIP, newNetmask ):
693 """
694 Changes the ip address of a host on the fly
695 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800696 if self.handle:
697 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800698 cmd = host + " ifconfig " + intf + " " + \
699 newIP + " " + 'netmask' + " " + newNetmask
700 self.handle.sendline( cmd )
701 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800702 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800703 main.log.info( "response = " + response )
704 main.log.info(
705 "Ip of host " +
706 host +
707 " changed to new IP " +
708 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800709 return main.TRUE
710 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 main.log.error( self.name + ": EOF exception found" )
712 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800713 return main.FALSE
714
Jon Hall7eb38402015-01-08 17:19:54 -0800715 def changeDefaultGateway( self, host, newGW ):
716 """
717 Changes the default gateway of a host
718 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800719 if self.handle:
720 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800721 cmd = host + " route add default gw " + newGW
722 self.handle.sendline( cmd )
723 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800724 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800725 main.log.info( "response = " + response )
726 main.log.info(
727 "Default gateway of host " +
728 host +
729 " changed to " +
730 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800731 return main.TRUE
732 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800735 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800736
Jon Hall7eb38402015-01-08 17:19:54 -0800737 def addStaticMACAddress( self, host, GW, macaddr ):
738 """
Jon Hallefbd9792015-03-05 16:11:36 -0800739 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800740 if self.handle:
741 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800742 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
743 cmd = host + " arp -s " + GW + " " + macaddr
744 self.handle.sendline( cmd )
745 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800746 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800747 main.log.info( "response = " + response )
748 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800749 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800750 GW +
751 " changed to " +
752 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800753 return main.TRUE
754 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800755 main.log.error( self.name + ": EOF exception found" )
756 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800757 return main.FALSE
758
Jon Hall7eb38402015-01-08 17:19:54 -0800759 def verifyStaticGWandMAC( self, host ):
760 """
761 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800762 if self.handle:
763 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800764 # h1 arp -an
765 cmd = host + " arp -an "
766 self.handle.sendline( cmd )
767 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800768 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800769 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800770 return main.TRUE
771 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800774 return main.FALSE
775
Jon Hall7eb38402015-01-08 17:19:54 -0800776 def getMacAddress( self, host ):
777 """
778 Verifies the host's ip configured or not."""
779 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700780 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800781 response = self.execute(
782 cmd=host +
783 " ifconfig",
784 prompt="mininet>",
785 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800786 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800787 main.log.error( self.name + ": EOF exception found" )
788 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700789 main.cleanup()
790 main.exit()
adminbae64d82013-08-01 10:50:15 -0700791
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700792 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800793 macAddressSearch = re.search( pattern, response, re.I )
794 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800795 main.log.info(
796 self.name +
797 ": Mac-Address of Host " +
798 host +
799 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 macAddress )
801 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700802 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800803 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700804
Jon Hall7eb38402015-01-08 17:19:54 -0800805 def getInterfaceMACAddress( self, host, interface ):
806 """
807 Return the IP address of the interface on the given host"""
808 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700809 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800810 response = self.execute( cmd=host + " ifconfig " + interface,
811 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800812 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800813 main.log.error( self.name + ": EOF exception found" )
814 main.log.error( self.name + ": " + self.handle.before )
815 main.cleanup()
816 main.exit()
817
818 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 macAddressSearch = re.search( pattern, response, re.I )
820 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800821 main.log.info( "No mac address found in %s" % response )
822 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800824 main.log.info(
825 "Mac-Address of " +
826 host +
827 ":" +
828 interface +
829 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800830 macAddress )
831 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800832 else:
833 main.log.error( "Connection failed to the host" )
834
835 def getIPAddress( self, host ):
836 """
837 Verifies the host's ip configured or not."""
838 if self.handle:
839 try:
840 response = self.execute(
841 cmd=host +
842 " ifconfig",
843 prompt="mininet>",
844 timeout=10 )
845 except pexpect.EOF:
846 main.log.error( self.name + ": EOF exception found" )
847 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700848 main.cleanup()
849 main.exit()
adminbae64d82013-08-01 10:50:15 -0700850
851 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800853 main.log.info(
854 self.name +
855 ": IP-Address of Host " +
856 host +
857 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800858 ipAddressSearch.group( 1 ) )
859 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800860 else:
861 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800862
Jon Hall7eb38402015-01-08 17:19:54 -0800863 def getSwitchDPID( self, switch ):
864 """
865 return the datapath ID of the switch"""
866 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700867 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700868 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800869 response = self.execute(
870 cmd=cmd,
871 prompt="mininet>",
872 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800873 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800874 main.log.error( self.name + ": EOF exception found" )
875 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700876 main.cleanup()
877 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800878 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800879 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700880 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800881 main.log.info(
882 "Couldn't find DPID for switch %s, found: %s" %
883 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700884 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800885 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700886 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700888
Jon Hall7eb38402015-01-08 17:19:54 -0800889 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700890 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800891 self.handle.sendline( "" )
892 self.expect( "mininet>" )
893 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700894 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800895 response = self.execute(
896 cmd=cmd,
897 prompt="mininet>",
898 timeout=10 )
899 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700900 response = self.handle.before
901 return response
902 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800903 main.log.error( self.name + ": EOF exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700905 main.cleanup()
906 main.exit()
907
Jon Hall7eb38402015-01-08 17:19:54 -0800908 def getInterfaces( self, node ):
909 """
910 return information dict about interfaces connected to the node"""
911 if self.handle:
912 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800913 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700914 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700915 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800916 response = self.execute(
917 cmd=cmd,
918 prompt="mininet>",
919 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800920 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800921 main.log.error( self.name + ": EOF exception found" )
922 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700923 main.cleanup()
924 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700925 return response
926 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800927 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700928
Jon Hall7eb38402015-01-08 17:19:54 -0800929 def dump( self ):
930 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700931 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800932 response = self.execute(
933 cmd='dump',
934 prompt='mininet>',
935 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800936 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700939 main.cleanup()
940 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700941 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800942
Jon Hall7eb38402015-01-08 17:19:54 -0800943 def intfs( self ):
944 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700945 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800946 response = self.execute(
947 cmd='intfs',
948 prompt='mininet>',
949 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800950 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800951 main.log.error( self.name + ": EOF exception found" )
952 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700953 main.cleanup()
954 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700955 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800956
Jon Hall7eb38402015-01-08 17:19:54 -0800957 def net( self ):
958 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700959 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800960 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800961 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700964 main.cleanup()
965 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700966 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800967
Jon Hallafa8a472015-06-12 14:02:42 -0700968 def links( self ):
969 main.log.info( self.name + ": List network links" )
970 try:
971 response = self.execute( cmd='links', prompt='mininet>',
972 timeout=10 )
973 except pexpect.EOF:
974 main.log.error( self.name + ": EOF exception found" )
975 main.log.error( self.name + ": " + self.handle.before )
976 main.cleanup()
977 main.exit()
978 return response
979
GlennRC61321f22015-07-16 13:36:54 -0700980 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700981 '''
982 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -0700983
kelvin-onlab7cce9382015-07-17 10:21:03 -0700984 @parm:
985 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
986 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
987 '''
988 for host1 in hosts:
989 for host2 in hosts:
990 if host1 != host2:
991 if self.iperftcp(host1, host2, timeout) == main.FALSE:
992 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
GlennRC61321f22015-07-16 13:36:54 -0700993
994 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700995 '''
996 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
997 are valid.
GlennRC61321f22015-07-16 13:36:54 -0700998
kelvin-onlab7cce9382015-07-17 10:21:03 -0700999 @parm:
1000 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1001 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1002 '''
1003 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1004 try:
1005 # Setup the mininet command
1006 cmd1 = 'iperf ' + host1 + " " + host2
1007 self.handle.sendline( cmd1 )
1008 outcome = self.handle.expect( "mininet>", timeout )
1009 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001010
kelvin-onlab7cce9382015-07-17 10:21:03 -07001011 # checks if there are results in the mininet response
1012 if "Results:" in response:
1013 main.log.report(self.name + ": iperf test completed")
1014 # parse the mn results
1015 response = response.split("\r\n")
1016 response = response[len(response)-2]
1017 response = response.split(": ")
1018 response = response[len(response)-1]
1019 response = response.replace("[", "")
1020 response = response.replace("]", "")
1021 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001022
kelvin-onlab7cce9382015-07-17 10:21:03 -07001023 # this is the bandwith two and from the two hosts
1024 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001025
kelvin-onlab7cce9382015-07-17 10:21:03 -07001026 # there should be two elements in the bandwidth list
1027 # ['host1 to host2', 'host2 to host1"]
1028 if len(bandwidth) == 2:
1029 main.log.report(self.name + ": iperf test successful")
1030 return main.TRUE
1031 else:
1032 main.log.error(self.name + ": invalid iperf results")
1033 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001034 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001035 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001036 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001037
GlennRC61321f22015-07-16 13:36:54 -07001038 except pexpect.TIMEOUT:
1039 main.log.error( self.name + ": TIMEOUT exception found")
1040 main.log.error( self.name + ": Exception: Cannot connect to iperf on port 5001" )
1041 return main.FALSE
1042
Jon Hallfbc828e2015-01-06 17:30:19 -08001043 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001044 main.log.error( self.name + ": EOF exception found" )
1045 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001046 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001047 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001048
1049 def iperfudpAll(self, hosts, bandwidth="10M"):
1050 '''
1051 Runs the iperfudp function with a given set of hosts and specified
1052 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001053
GlennRC61321f22015-07-16 13:36:54 -07001054 @param:
1055 bandwidth: the targeted bandwidth, in megabits ('M')
1056 '''
1057 for host1 in hosts:
1058 for host2 in hosts:
1059 if host1 != host2:
1060 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1061 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1062
1063 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1064
kelvin-onlab7cce9382015-07-17 10:21:03 -07001065 '''
1066 Creates an iperf UDP test with a specific bandwidth.
1067 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001068
kelvin-onlab7cce9382015-07-17 10:21:03 -07001069 @param:
1070 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1071 '''
1072 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1073 try:
1074 # setup the mininet command
1075 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1076 self.handle.sendline(cmd)
1077 self.handle.expect("mininet>")
1078 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001079
kelvin-onlab7cce9382015-07-17 10:21:03 -07001080 # check if there are in results in the mininet response
1081 if "Results:" in response:
1082 main.log.report(self.name + ": iperfudp test completed")
1083 # parse the results
1084 response = response.split("\r\n")
1085 response = response[len(response)-2]
1086 response = response.split(": ")
1087 response = response[len(response)-1]
1088 response = response.replace("[", "")
1089 response = response.replace("]", "")
1090 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001091
kelvin-onlab7cce9382015-07-17 10:21:03 -07001092 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001093
kelvin-onlab7cce9382015-07-17 10:21:03 -07001094 # check to see if there are at least three entries
1095 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1096 if len(mnBandwidth) == 3:
1097 # if one entry is blank then something is wrong
1098 for item in mnBandwidth:
1099 if item == "":
1100 main.log.error(self.name + ": Could not parse iperf output")
1101 main.log.error(self.name + ": invalid iperfudp results")
1102 return main.FALSE
1103 # otherwise results are vaild
1104 main.log.report(self.name + ": iperfudp test successful")
1105 return main.TRUE
1106 else:
1107 main.log.error(self.name + ": invalid iperfudp results")
1108 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001109
kelvin-onlab7cce9382015-07-17 10:21:03 -07001110 except pexpect.EOF:
1111 main.log.error( self.name + ": EOF exception found" )
1112 main.log.error( self.name + ": " + self.handle.before )
1113 main.cleanup()
1114 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001115
Jon Hall7eb38402015-01-08 17:19:54 -08001116 def nodes( self ):
1117 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001118 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001119 response = self.execute(
1120 cmd='nodes',
1121 prompt='mininet>',
1122 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001123 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001126 main.cleanup()
1127 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001128 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001129
Jon Hall7eb38402015-01-08 17:19:54 -08001130 def pingpair( self ):
1131 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001132 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 response = self.execute(
1134 cmd='pingpair',
1135 prompt='mininet>',
1136 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001137 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001138 main.log.error( self.name + ": EOF exception found" )
1139 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001140 main.cleanup()
1141 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001142
Jon Hall7eb38402015-01-08 17:19:54 -08001143 if re.search( ',\s0\%\spacket\sloss', response ):
1144 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -07001146 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001147 else:
1148 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -07001150 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001151
Jon Hall7eb38402015-01-08 17:19:54 -08001152 def link( self, **linkargs ):
1153 """
1154 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001155 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001156 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1157 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1158 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1159 main.log.info(
1160 "Bring link between '" +
1161 end1 +
1162 "' and '" +
1163 end2 +
1164 "' '" +
1165 option +
1166 "'" )
1167 command = "link " + \
1168 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001169 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001170 self.handle.sendline( command )
1171 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001172 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001173 main.log.error( self.name + ": EOF exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001175 main.cleanup()
1176 main.exit()
adminbae64d82013-08-01 10:50:15 -07001177 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001178
Jon Hall7eb38402015-01-08 17:19:54 -08001179 def yank( self, **yankargs ):
1180 """
1181 yank a mininet switch interface to a host"""
1182 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001183 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001184 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1185 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1186 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001187 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001188 response = self.execute(
1189 cmd=command,
1190 prompt="mininet>",
1191 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001192 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001193 main.log.error( self.name + ": EOF exception found" )
1194 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001195 main.cleanup()
1196 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001197 return main.TRUE
1198
Jon Hall7eb38402015-01-08 17:19:54 -08001199 def plug( self, **plugargs ):
1200 """
1201 plug the yanked mininet switch interface to a switch"""
1202 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001203 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001204 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1205 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1206 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001207 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001208 response = self.execute(
1209 cmd=command,
1210 prompt="mininet>",
1211 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001212 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001213 main.log.error( self.name + ": EOF exception found" )
1214 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001215 main.cleanup()
1216 main.exit()
adminbae64d82013-08-01 10:50:15 -07001217 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001218
Jon Hall7eb38402015-01-08 17:19:54 -08001219 def dpctl( self, **dpctlargs ):
1220 """
1221 Run dpctl command on all switches."""
1222 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001223 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001224 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1225 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1226 command = "dpctl " + cmd + " " + str( cmdargs )
1227 try:
1228 response = self.execute(
1229 cmd=command,
1230 prompt="mininet>",
1231 timeout=10 )
1232 except pexpect.EOF:
1233 main.log.error( self.name + ": EOF exception found" )
1234 main.log.error( self.name + ": " + self.handle.before )
1235 main.cleanup()
1236 main.exit()
1237 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001238
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001240 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001241 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 fileInput = path + '/lib/Mininet/INSTALL'
1243 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001244 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001246 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001247 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001248 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001249 return version
adminbae64d82013-08-01 10:50:15 -07001250
kelvin-onlabd3b64892015-01-20 13:26:24 -08001251 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001252 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001253 Parameters:
1254 sw: The name of an OVS switch. Example "s1"
1255 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001256 The output of the command from the mininet cli
1257 or main.FALSE on timeout"""
1258 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001259 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001260 response = self.execute(
1261 cmd=command,
1262 prompt="mininet>",
1263 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001264 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001265 return response
admin2a9548d2014-06-17 14:08:07 -07001266 else:
1267 return main.FALSE
1268 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001269 main.log.error( self.name + ": EOF exception found" )
1270 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001271 main.cleanup()
1272 main.exit()
adminbae64d82013-08-01 10:50:15 -07001273
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001274 def assignSwController( self, sw, ip, port="6633", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001275 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001276 Description:
1277 Assign switches to the controllers ( for ovs use only )
1278 Required:
1279 sw - Name of the switch. This can be a list or a string.
1280 ip - Ip addresses of controllers. This can be a list or a string.
1281 Optional:
1282 port - ONOS use port 6633, if no list of ports is passed, then
1283 the all the controller will use 6633 as their port number
1284 ptcp - ptcp number, This can be a string or a list that has
1285 the same length as switch. This is optional and not required
1286 when using ovs switches.
1287 NOTE: If switches and ptcp are given in a list type they should have the
1288 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1289 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001290
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001291 Return:
1292 Returns main.TRUE if mininet correctly assigned switches to
1293 controllers, otherwise it will return main.FALSE or an appropriate
1294 exception(s)
1295 """
1296 assignResult = main.TRUE
1297 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001298 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001299 command = "sh ovs-vsctl set-controller "
1300 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001301 try:
1302 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001303 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001304 if isinstance( port, types.StringType ) or \
1305 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001306 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001307 elif isinstance( port, types.ListType ):
1308 main.log.error( self.name + ": Only one controller " +
1309 "assigned and a list of ports has" +
1310 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001311 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001312 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001313 main.log.error( self.name + ": Invalid controller port " +
1314 "number. Please specify correct " +
1315 "controller port" )
1316 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001317
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001318 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001319 if isinstance( port, types.StringType ) or \
1320 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001321 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001322 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1323 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001324 elif isinstance( port, types.ListType ):
1325 if ( len( ip ) != len( port ) ):
1326 main.log.error( self.name + ": Port list = " +
1327 str( len( port ) ) +
1328 "should be the same as controller" +
1329 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001330 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001331 else:
1332 onosIp = ""
1333 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001334 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1335 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001336 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001337 main.log.error( self.name + ": Invalid controller port " +
1338 "number. Please specify correct " +
1339 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001340 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001341 else:
1342 main.log.error( self.name + ": Invalid ip address" )
1343 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001344
1345 if isinstance( sw, types.StringType ):
1346 command += sw + " "
1347 if ptcp:
1348 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001349 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001350 elif isinstance( ptcp, types.ListType ):
1351 main.log.error( self.name + ": Only one switch is " +
1352 "being set and multiple PTCP is " +
1353 "being passed " )
1354 else:
1355 main.log.error( self.name + ": Invalid PTCP" )
1356 ptcp = ""
1357 command += onosIp
1358 commandList.append( command )
1359
1360 elif isinstance( sw, types.ListType ):
1361 if ptcp:
1362 if isinstance( ptcp, types.ListType ):
1363 if len( ptcp ) != len( sw ):
1364 main.log.error( self.name + ": PTCP length = " +
1365 str( len( ptcp ) ) +
1366 " is not the same as switch" +
1367 " length = " +
1368 str( len( sw ) ) )
1369 return main.FALSE
1370 else:
1371 for switch, ptcpNum in zip( sw, ptcp ):
1372 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001373 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001374 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001375 tempCmd += onosIp
1376 commandList.append( tempCmd )
1377 else:
1378 main.log.error( self.name + ": Invalid PTCP" )
1379 return main.FALSE
1380 else:
1381 for switch in sw:
1382 tempCmd = "sh ovs-vsctl set-controller "
1383 tempCmd += switch + " " + onosIp
1384 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001385 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001386 main.log.error( self.name + ": Invalid switch type " )
1387 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001388
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001389 for cmd in commandList:
1390 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001391 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001392 except pexpect.TIMEOUT:
1393 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1394 return main.FALSE
1395 except pexpect.EOF:
1396 main.log.error( self.name + ": EOF exception found" )
1397 main.log.error( self.name + ": " + self.handle.before )
1398 main.cleanup()
1399 main.exit()
1400 return main.TRUE
1401 except Exception:
1402 main.log.exception( self.name + ": Uncaught exception!" )
1403 main.cleanup()
1404 main.exit()
adminbae64d82013-08-01 10:50:15 -07001405
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001407 """
1408 Removes the controller target from sw"""
1409 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001410 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001411 response = self.execute(
1412 cmd=command,
1413 prompt="mininet>",
1414 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001415 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001416 main.log.error( self.name + ": EOF exception found" )
1417 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001418 main.cleanup()
1419 main.exit()
1420 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001421 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001422
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001424 """
Jon Hallb1290e82014-11-18 16:17:48 -05001425 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001426 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001427 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001428 NOTE: cannot currently specify what type of switch
1429 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001430 sw = name of the new switch as a string
1431 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001432 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001433 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001434 """
1435 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001436 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001437 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001438 response = self.execute(
1439 cmd=command,
1440 prompt="mininet>",
1441 timeout=10 )
1442 if re.search( "already exists!", response ):
1443 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001444 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001445 elif re.search( "Error", response ):
1446 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001447 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001448 elif re.search( "usage:", response ):
1449 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001450 return main.FALSE
1451 else:
1452 return main.TRUE
1453 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001454 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001455 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001456 main.cleanup()
1457 main.exit()
1458
kelvin-onlabd3b64892015-01-20 13:26:24 -08001459 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001460 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001461 delete a switch from the mininet topology
1462 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001463 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001464 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001465 sw = name of the switch as a string
1466 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001467 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001468 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001469 response = self.execute(
1470 cmd=command,
1471 prompt="mininet>",
1472 timeout=10 )
1473 if re.search( "no switch named", response ):
1474 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001475 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001476 elif re.search( "Error", response ):
1477 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001478 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001479 elif re.search( "usage:", response ):
1480 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001481 return main.FALSE
1482 else:
1483 return main.TRUE
1484 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001485 main.log.error( self.name + ": EOF exception found" )
1486 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001487 main.cleanup()
1488 main.exit()
1489
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001491 """
1492 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001493 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001494 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001495 NOTE: cannot currently specify what type of link
1496 required params:
1497 node1 = the string node name of the first endpoint of the link
1498 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001499 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001500 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001501 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001502 response = self.execute(
1503 cmd=command,
1504 prompt="mininet>",
1505 timeout=10 )
1506 if re.search( "doesnt exist!", response ):
1507 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001508 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001509 elif re.search( "Error", response ):
1510 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001511 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001512 elif re.search( "usage:", response ):
1513 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001514 return main.FALSE
1515 else:
1516 return main.TRUE
1517 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001518 main.log.error( self.name + ": EOF exception found" )
1519 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001520 main.cleanup()
1521 main.exit()
1522
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001524 """
1525 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001526 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001527 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001528 required params:
1529 node1 = the string node name of the first endpoint of the link
1530 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001531 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001532 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001533 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001534 response = self.execute(
1535 cmd=command,
1536 prompt="mininet>",
1537 timeout=10 )
1538 if re.search( "no node named", response ):
1539 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001540 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001541 elif re.search( "Error", response ):
1542 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001543 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001544 elif re.search( "usage:", response ):
1545 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001546 return main.FALSE
1547 else:
1548 return main.TRUE
1549 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001550 main.log.error( self.name + ": EOF exception found" )
1551 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001552 main.cleanup()
1553 main.exit()
1554
kelvin-onlabd3b64892015-01-20 13:26:24 -08001555 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001556 """
Jon Hallb1290e82014-11-18 16:17:48 -05001557 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001558 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001559 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001560 NOTE: cannot currently specify what type of host
1561 required params:
1562 hostname = the string hostname
1563 optional key-value params
1564 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001565 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001566 """
1567 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001568 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001569 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001570 response = self.execute(
1571 cmd=command,
1572 prompt="mininet>",
1573 timeout=10 )
1574 if re.search( "already exists!", response ):
1575 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001576 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001577 elif re.search( "doesnt exists!", response ):
1578 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001579 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001580 elif re.search( "Error", response ):
1581 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001582 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001583 elif re.search( "usage:", response ):
1584 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001585 return main.FALSE
1586 else:
1587 return main.TRUE
1588 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001589 main.log.error( self.name + ": EOF exception found" )
1590 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001591 main.cleanup()
1592 main.exit()
1593
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001595 """
1596 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001597 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001598 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001599 NOTE: this uses a custom mn function
1600 required params:
1601 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001602 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001603 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001604 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001605 response = self.execute(
1606 cmd=command,
1607 prompt="mininet>",
1608 timeout=10 )
1609 if re.search( "no host named", response ):
1610 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001611 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001612 elif re.search( "Error", response ):
1613 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001614 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001615 elif re.search( "usage:", response ):
1616 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001617 return main.FALSE
1618 else:
1619 return main.TRUE
1620 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001621 main.log.error( self.name + ": EOF exception found" )
1622 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001623 main.cleanup()
1624 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001625
Jon Hall7eb38402015-01-08 17:19:54 -08001626 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001627 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001628 Called at the end of the test to stop the mininet and
1629 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001630 """
Jon Halld80cc142015-07-06 13:36:05 -07001631 self.handle.sendline( '' )
Jon Halld61331b2015-02-17 16:35:47 -08001632 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -07001633 timeout=2 )
Jon Hall390696c2015-05-05 17:13:41 -07001634 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001635 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001636 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001637 elif i == 1:
1638 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001639 # print "Disconnecting Mininet"
1640 if self.handle:
1641 self.handle.sendline( "exit" )
1642 self.handle.expect( "exit" )
1643 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001644 else:
1645 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001646 return response
1647
Jon Halld80cc142015-07-06 13:36:05 -07001648 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001649 """
Jon Hall21270ac2015-02-16 17:59:55 -08001650 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001651 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001652 main.FALSE if the pexpect handle does not exist.
1653
Jon Halld61331b2015-02-17 16:35:47 -08001654 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001655 """
Jon Halld61331b2015-02-17 16:35:47 -08001656 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001657 response = ''
1658 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001659 try:
Jon Halld80cc142015-07-06 13:36:05 -07001660 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08001661 i = self.handle.expect( [ 'mininet>',
1662 '\$',
1663 pexpect.EOF,
1664 pexpect.TIMEOUT ],
1665 timeout )
1666 if i == 0:
1667 main.log.info( "Exiting mininet..." )
Jon Hall7eb38402015-01-08 17:19:54 -08001668 response = self.execute(
1669 cmd="exit",
1670 prompt="(.*)",
1671 timeout=120 )
Jon Halld80cc142015-07-06 13:36:05 -07001672 main.log.info( self.name + ": Stopped" )
Jon Hall7eb38402015-01-08 17:19:54 -08001673 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001674 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001675
kelvin-onlab56a3f462015-02-06 14:04:43 -08001676 if i == 1:
1677 main.log.info( " Mininet trying to exit while not " +
1678 "in the mininet prompt" )
1679 elif i == 2:
1680 main.log.error( "Something went wrong exiting mininet" )
1681 elif i == 3: # timeout
1682 main.log.error( "Something went wrong exiting mininet " +
1683 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07001684
Hari Krishnab35c6d02015-03-18 11:13:51 -07001685 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07001686 self.handle.sendline( "" )
1687 self.handle.expect( '\$' )
1688 self.handle.sendline(
1689 "sudo kill -9 \`ps -ef | grep \"" +
1690 fileName +
1691 "\" | grep -v grep | awk '{print $2}'\`" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001692 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001693 main.log.error( self.name + ": EOF exception found" )
1694 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001695 main.cleanup()
1696 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001697 else:
1698 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001699 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001700 return response
1701
kelvin-onlabf0594d72015-05-19 17:25:12 -07001702 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001703 """
1704 Description:
1705 Sends arp message from mininet host for hosts discovery
1706 Required:
1707 host - hosts name
1708 Optional:
1709 ip - ip address that does not exist in the network so there would
1710 be no reply.
1711 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001712 if ethDevice:
1713 ethDevice = '-I ' + ethDevice + ' '
Jon Halld80cc142015-07-06 13:36:05 -07001714 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001715 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001716 main.log.warn( "Sending: " + cmd )
1717 self.handle.sendline( cmd )
1718 response = self.handle.before
1719 self.handle.sendline( "" )
1720 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001721 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001722
1723 except pexpect.EOF:
1724 main.log.error( self.name + ": EOF exception found" )
1725 main.log.error( self.name + ": " + self.handle.before )
1726 main.cleanup()
1727 main.exit()
admin07529932013-11-22 14:58:28 -08001728
Jon Hall7eb38402015-01-08 17:19:54 -08001729 def decToHex( self, num ):
1730 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001731
Jon Hall7eb38402015-01-08 17:19:54 -08001732 def getSwitchFlowCount( self, switch ):
1733 """
1734 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001735 if self.handle:
1736 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1737 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001738 response = self.execute(
1739 cmd=cmd,
1740 prompt="mininet>",
1741 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001742 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001743 main.log.error( self.name + ": EOF exception found" )
1744 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001745 main.cleanup()
1746 main.exit()
1747 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001748 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001749 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001750 main.log.info(
1751 "Couldn't find flows on switch %s, found: %s" %
1752 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001753 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001754 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001755 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001756 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001757
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 def checkFlows( self, sw, dumpFormat=None ):
1759 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001760 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001762 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001763 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001764 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001765 response = self.execute(
1766 cmd=command,
1767 prompt="mininet>",
1768 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001769 return response
1770 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001771 main.log.error( self.name + ": EOF exception found" )
1772 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001773 main.cleanup()
1774 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001775
Jon Hall9043c902015-07-30 14:23:44 -07001776 def getFlowTable( self, protoVersion, sw ):
1777 """
1778 Returns certain fields of an OVS flow table. Will force output to
1779 either OF 1.0 or 1.3 format for consistency.
1780
1781 TODO add option to look at cookies. ignoring them for now
1782
1783 NOTE: Use format to force consistent flow table output across
1784 versions
1785 """
1786 try:
1787 self.handle.sendline( "" )
1788 self.handle.expect( "mininet>" )
1789 command = "sh ovs-ofctl dump-flows " + sw
1790 if protoVersion == 1.0:
1791 command += " -F OpenFlow10-table_id | awk '{OFS=\",\" ;" +\
1792 " print $1 $3 $6 $7 $8}' | "
1793 elif protoVersion == 1.3:
1794 command += " -O OpenFlow13 | awk '{OFS=\",\" ;" +\
1795 " print $1 $3 $6 $7}' | "
1796 else:
1797 main.log.error(
1798 "Unknown protoVersion in getFlowTable(). given: (" +
1799 str( type( protoVersion ) ) +
1800 ") '" + str( protoVersion ) + "'" )
1801 return None
1802 command += "cut -d ',' -f 2- | sort -n -k1 -r"
1803 self.handle.sendline( command )
1804 self.handle.expect( "sort" )
1805 self.handle.expect( "OFPST_FLOW" )
1806 response = self.handle.before
1807 return response
1808 except pexpect.EOF:
1809 main.log.error( self.name + ": EOF exception found" )
1810 main.log.error( self.name + ": " + self.handle.before )
1811 main.cleanup()
1812 main.exit()
1813 except pexpect.TIMEOUT:
1814 main.log.exception( self.name + ": Timeout exception: " )
1815 return None
1816
1817 def flowComp( self, flow1, flow2 ):
1818 if flow1 == flow2:
1819 return main.TRUE
1820 else:
1821 main.log.info( "Flow tables do not match, printing tables:" )
1822 main.log.info( "Flow Table 1:" )
1823 main.log.info( flow1 )
1824 main.log.info( "Flow Table 2:" )
1825 main.log.info( flow2 )
1826 return main.FALSE
1827
kelvin-onlabd3b64892015-01-20 13:26:24 -08001828 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001829 """
Jon Hallefbd9792015-03-05 16:11:36 -08001830 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001831 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001832 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001833 self.handle.sendline( "" )
1834 self.handle.expect( "mininet>" )
1835 self.handle.sendline(
1836 "sh sudo tcpdump -n -i " +
1837 intf +
1838 " " +
1839 port +
1840 " -w " +
1841 filename.strip() +
1842 " &" )
1843 self.handle.sendline( "" )
1844 i = self.handle.expect( [ 'No\ssuch\device',
1845 'listening\son',
1846 pexpect.TIMEOUT,
1847 "mininet>" ],
1848 timeout=10 )
1849 main.log.warn( self.handle.before + self.handle.after )
1850 self.handle.sendline( "" )
1851 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001852 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001853 main.log.error(
1854 self.name +
1855 ": tcpdump - No such device exists. " +
1856 "tcpdump attempted on: " +
1857 intf )
admin2a9548d2014-06-17 14:08:07 -07001858 return main.FALSE
1859 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001860 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001861 return main.TRUE
1862 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001863 main.log.error(
1864 self.name +
1865 ": tcpdump command timed out! Check interface name," +
1866 " given interface was: " +
1867 intf )
admin2a9548d2014-06-17 14:08:07 -07001868 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001869 elif i == 3:
1870 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001871 return main.TRUE
1872 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001873 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001874 return main.FALSE
1875 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001876 main.log.error( self.name + ": EOF exception found" )
1877 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001878 main.cleanup()
1879 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001880 except Exception:
1881 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001882 main.cleanup()
1883 main.exit()
1884
kelvin-onlabd3b64892015-01-20 13:26:24 -08001885 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001886 """
1887 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001888 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001889 self.handle.sendline( "sh sudo pkill tcpdump" )
1890 self.handle.expect( "mininet>" )
1891 self.handle.sendline( "" )
1892 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001893 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001894 main.log.error( self.name + ": EOF exception found" )
1895 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001896 main.cleanup()
1897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001898 except Exception:
1899 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001900 main.cleanup()
1901 main.exit()
1902
Jon Halld80cc142015-07-06 13:36:05 -07001903 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001904 """
1905 Read ports from a Mininet switch.
1906
1907 Returns a json structure containing information about the
1908 ports of the given switch.
1909 """
1910 response = self.getInterfaces( nodeName )
1911 # TODO: Sanity check on response. log if no such switch exists
1912 ports = []
1913 for line in response.split( "\n" ):
1914 if not line.startswith( "name=" ):
1915 continue
1916 portVars = {}
1917 for var in line.split( "," ):
1918 key, value = var.split( "=" )
1919 portVars[ key ] = value
1920 isUp = portVars.pop( 'enabled', "True" )
1921 isUp = "True" in isUp
1922 if verbose:
1923 main.log.info( "Reading switch port %s(%s)" %
1924 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
1925 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001926 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001927 mac = None
1928 ips = []
1929 ip = portVars[ 'ip' ]
1930 if ip == 'None':
1931 ip = None
1932 ips.append( ip )
1933 name = portVars[ 'name' ]
1934 if name == 'None':
1935 name = None
1936 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
1937 if name == 'lo':
1938 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
1939 else:
1940 portNo = re.search( portRe, name ).group( 'port' )
1941 ports.append( { 'of_port': portNo,
1942 'mac': str( mac ).replace( '\'', '' ),
1943 'name': name,
1944 'ips': ips,
1945 'enabled': isUp } )
1946 return ports
1947
Jon Halld80cc142015-07-06 13:36:05 -07001948 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001949 """
1950 Read switches from Mininet.
1951
1952 Returns a dictionary whose keys are the switch names and the value is
1953 a dictionary containing information about the switch.
1954 """
Jon Halla22481b2015-07-28 17:46:01 -07001955 # NOTE: To support new Mininet switch classes, just append the new
1956 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07001957
Jon Halla22481b2015-07-28 17:46:01 -07001958 # Regex patterns to parse 'dump' output
1959 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07001960 # <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 -07001961 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07001962 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
1963 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
1964 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
1965 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
1966 swRE = r"<(?P<class>" + switchClasses + r")" +\
1967 r"(?P<options>\{.*\})?\s" +\
1968 r"(?P<name>[^:]+)\:\s" +\
1969 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
1970 r"\spid=(?P<pid>(\d)+)"
Jon Hallafa8a472015-06-12 14:02:42 -07001971 # Update mn port info
1972 self.update()
Jon Halld80cc142015-07-06 13:36:05 -07001973 output = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001974 dump = self.dump().split( "\n" )
1975 for line in dump:
Jon Halla22481b2015-07-28 17:46:01 -07001976 result = re.search( swRE, line, re.I )
1977 if result:
Jon Hallafa8a472015-06-12 14:02:42 -07001978 name = result.group( 'name' )
1979 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
Jon Halla22481b2015-07-28 17:46:01 -07001980 pid = result.group( 'pid' )
1981 swClass = result.group( 'class' )
1982 options = result.group( 'options' )
Jon Hallafa8a472015-06-12 14:02:42 -07001983 if verbose:
1984 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
1985 ports = self.getPorts( name )
Jon Halla22481b2015-07-28 17:46:01 -07001986 output[ name ] = { "dpid": dpid,
1987 "ports": ports,
1988 "swClass": swClass,
1989 "pid": pid,
1990 "options": options }
Jon Hallafa8a472015-06-12 14:02:42 -07001991 return output
1992
Jon Halld80cc142015-07-06 13:36:05 -07001993 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001994 """
1995 Read hosts from Mininet.
1996
1997 Returns a dictionary whose keys are the host names and the value is
1998 a dictionary containing information about the host.
1999 """
2000 # Regex patterns to parse dump output
2001 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002002 # <Host h1: pid=12725>
2003 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2004 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2005 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002006 # NOTE: Does not correctly match hosts with multi-links
2007 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2008 # FIXME: Fix that
kelvin-onlabd48a68c2015-07-13 16:01:36 -07002009 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Jon Halld80cc142015-07-06 13:36:05 -07002010 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
Jon Hallafa8a472015-06-12 14:02:42 -07002011 # update mn port info
2012 self.update()
2013 # Get mininet dump
2014 dump = self.dump().split( "\n" )
Jon Hall5b0120a2015-06-12 17:35:53 -07002015 hosts = {}
Jon Hallafa8a472015-06-12 14:02:42 -07002016 for line in dump:
kelvin-onlabd48a68c2015-07-13 16:01:36 -07002017 if "Host" in line :
Jon Hallafa8a472015-06-12 14:02:42 -07002018 result = re.search( hostRE, line )
2019 name = result.group( 'name' )
2020 interfaces = []
2021 response = self.getInterfaces( name )
2022 # Populate interface info
2023 for line in response.split( "\n" ):
2024 if line.startswith( "name=" ):
2025 portVars = {}
2026 for var in line.split( "," ):
2027 key, value = var.split( "=" )
2028 portVars[ key ] = value
2029 isUp = portVars.pop( 'enabled', "True" )
2030 isUp = "True" in isUp
2031 if verbose:
2032 main.log.info( "Reading host port %s(%s)" %
2033 ( portVars[ 'name' ],
2034 portVars[ 'mac' ] ) )
2035 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07002036 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07002037 mac = None
2038 ips = []
2039 ip = portVars[ 'ip' ]
2040 if ip == 'None':
2041 ip = None
2042 ips.append( ip )
2043 intfName = portVars[ 'name' ]
2044 if name == 'None':
2045 name = None
2046 interfaces.append( {
2047 "name": intfName,
2048 "ips": ips,
2049 "mac": str( mac ),
2050 "isUp": isUp } )
Jon Hall5b0120a2015-06-12 17:35:53 -07002051 hosts[ name ] = { "interfaces": interfaces }
Jon Hallafa8a472015-06-12 14:02:42 -07002052 return hosts
2053
2054 def getLinks( self ):
2055 """
2056 Gathers information about current Mininet links. These links may not
2057 be up if one of the ports is down.
2058
2059 Returns a list of dictionaries with link endpoints.
2060
2061 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002062 { 'node1': str( node1 name )
2063 'node2': str( node2 name )
2064 'port1': str( port1 of_port )
2065 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002066 Note: The port number returned is the eth#, not necessarily the of_port
2067 number. In Mininet, for OVS switch, these should be the same. For
2068 hosts, this is just the eth#.
2069 """
2070 self.update()
2071 response = self.links().split( '\n' )
2072
2073 # Examples:
2074 # s1-eth3<->s2-eth1 (OK OK)
2075 # s13-eth3<->h27-eth0 (OK OK)
2076 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2077 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2078 links = []
2079 for line in response:
2080 match = re.search( linkRE, line )
2081 if match:
2082 node1 = match.group( 'node1' )
2083 node2 = match.group( 'node2' )
2084 port1 = match.group( 'port1' )
2085 port2 = match.group( 'port2' )
2086 links.append( { 'node1': node1,
2087 'node2': node2,
2088 'port1': port1,
2089 'port2': port2 } )
2090 return links
2091
2092 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002093 """
2094 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002095 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002096
Jon Hallafa8a472015-06-12 14:02:42 -07002097 Dependencies:
2098 1. numpy - "sudo pip install numpy"
2099 """
2100 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002101 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08002102 mnDPIDs = []
Jon Hallafa8a472015-06-12 14:02:42 -07002103 for swName, switch in switches.iteritems():
Jon Hall7eb38402015-01-08 17:19:54 -08002104 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002105 mnDPIDs.sort()
kelvin-onlabd3b64892015-01-20 13:26:24 -08002106 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08002107 main.log.error(
2108 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07002109 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04002110 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08002112 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04002113 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08002114 if switch[ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002115 onosDPIDs.append(
2116 switch[ 'id' ].replace(
2117 ":",
2118 '' ).replace(
2119 "of",
2120 '' ).lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002121 onosDPIDs.sort()
Jon Hall3d87d502014-10-17 18:37:42 -04002122
Jon Hall7eb38402015-01-08 17:19:54 -08002123 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002124 switchResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002125 main.log.error( "Switches in MN but not in ONOS:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002126 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002127 main.log.error( str( list1 ) )
2128 main.log.error( "Switches in ONOS but not in MN:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002129 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002130 main.log.error( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002131 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08002132 switchResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002133 finalResults = switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04002134
Jon Hall7eb38402015-01-08 17:19:54 -08002135 # FIXME: this does not look for extra ports in ONOS, only checks that
2136 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002137 portsResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002138
Jon Hall7eb38402015-01-08 17:19:54 -08002139 # PORTS
Jon Hallafa8a472015-06-12 14:02:42 -07002140 for name, mnSwitch in switches.iteritems():
kelvin-onlabd3b64892015-01-20 13:26:24 -08002141 mnPorts = []
2142 onosPorts = []
2143 switchResult = main.TRUE
2144 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002145 if port[ 'enabled' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002146 mnPorts.append( int( port[ 'of_port' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002147 for onosSwitch in portsJson:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002148 if onosSwitch[ 'device' ][ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002149 if onosSwitch[ 'device' ][ 'id' ].replace(
2150 ':',
2151 '' ).replace(
2152 "of",
2153 '' ) == mnSwitch[ 'dpid' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002154 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002155 if port[ 'isEnabled' ]:
2156 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08002157 # onosPorts.append( 'local' )
2158 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002159 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002161 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08002162 mnPorts.sort( key=float )
2163 onosPorts.sort( key=float )
Jon Hallafa8a472015-06-12 14:02:42 -07002164
kelvin-onlabd3b64892015-01-20 13:26:24 -08002165 mnPortsLog = mnPorts
2166 onosPortsLog = onosPorts
2167 mnPorts = [ x for x in mnPorts ]
2168 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05002169
Jon Hall7eb38402015-01-08 17:19:54 -08002170 # TODO: handle other reserved port numbers besides LOCAL
2171 # NOTE: Reserved ports
2172 # Local port: -2 in Openflow, ONOS shows 'local', we store as
2173 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 for mnPort in mnPortsLog:
2175 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08002176 # don't set results to true here as this is just one of
2177 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08002178 mnPorts.remove( mnPort )
2179 onosPorts.remove( mnPort )
Jon Hallafa8a472015-06-12 14:02:42 -07002180
Jon Hall7eb38402015-01-08 17:19:54 -08002181 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05002182 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08002183 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08002184 if 65534 in mnPorts:
2185 mnPorts.remove( 65534 )
2186 if long( uint64( -2 ) ) in onosPorts:
2187 onosPorts.remove( long( uint64( -2 ) ) )
2188 if len( mnPorts ): # the ports of this switch don't match
2189 switchResult = main.FALSE
2190 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
2191 if len( onosPorts ): # the ports of this switch don't match
2192 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002193 main.log.warn(
2194 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 str( onosPorts ) )
2196 if switchResult == main.FALSE:
Jon Hallafa8a472015-06-12 14:02:42 -07002197 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002198 "The list of ports for switch %s(%s) does not match:" %
Jon Hallafa8a472015-06-12 14:02:42 -07002199 ( name, mnSwitch[ 'dpid' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002200 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
2201 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
2202 portsResults = portsResults and switchResult
Jon Hallafa8a472015-06-12 14:02:42 -07002203 finalResults = finalResults and portsResults
2204 return finalResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002205
Jon Hallafa8a472015-06-12 14:02:42 -07002206 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002207 """
2208 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002209 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04002210
Jon Hallafa8a472015-06-12 14:02:42 -07002211 """
Jon Hall7eb38402015-01-08 17:19:54 -08002212 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08002213 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002214 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04002215
Jon Halld80cc142015-07-06 13:36:05 -07002216 mnLinks = []
Jon Hallafa8a472015-06-12 14:02:42 -07002217 for l in links:
2218 try:
2219 node1 = switches[ l[ 'node1' ] ]
2220 node2 = switches[ l[ 'node2' ] ]
2221 enabled = True
2222 for port in node1[ 'ports' ]:
2223 if port[ 'of_port' ] == l[ 'port1' ]:
2224 enabled = enabled and port[ 'enabled' ]
2225 for port in node2[ 'ports' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002226 if port[ 'of_port' ] == l[ 'port2' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002227 enabled = enabled and port[ 'enabled' ]
2228 if enabled:
2229 mnLinks.append( l )
2230 except KeyError:
2231 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002232 if 2 * len( mnLinks ) == len( onos ):
2233 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002234 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002235 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002236 main.log.error(
Jon Hall328ddca2015-01-28 15:57:15 -08002237 "Mininet has " + str( len( mnLinks ) ) +
2238 " bidirectional links and ONOS has " +
2239 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002240
Jon Hall7eb38402015-01-08 17:19:54 -08002241 # iterate through MN links and check if an ONOS link exists in
2242 # both directions
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08002244 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04002245 node1 = None
2246 port1 = None
2247 node2 = None
2248 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08002249 firstDir = main.FALSE
2250 secondDir = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002251 for swName, switch in switches.iteritems():
2252 if swName == link[ 'node1' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002253 node1 = switch[ 'dpid' ]
2254 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002255 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002256 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002257 if node1 is not None and node2 is not None:
2258 break
Jon Hallafa8a472015-06-12 14:02:42 -07002259 if swName == link[ 'node2' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002260 node2 = switch[ 'dpid' ]
2261 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002262 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002263 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002264 if node1 is not None and node2 is not None:
2265 break
2266
kelvin-onlabd3b64892015-01-20 13:26:24 -08002267 for onosLink in onos:
2268 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002269 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002270 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002271 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002272 onosPort1 = onosLink[ 'src' ][ 'port' ]
2273 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002274
Jon Hall72cf1dc2014-10-20 21:04:50 -04002275 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 if str( onosNode1 ) == str( node1 ) and str(
2277 onosNode2 ) == str( node2 ):
2278 if int( onosPort1 ) == int( port1 ) and int(
2279 onosPort2 ) == int( port2 ):
2280 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002281 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002282 main.log.warn(
2283 'The port numbers do not match for ' +
2284 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002285 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002286 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002287 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002288 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002289 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002290
2291 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 elif ( str( onosNode1 ) == str( node2 ) and
2293 str( onosNode2 ) == str( node1 ) ):
2294 if ( int( onosPort1 ) == int( port2 )
2295 and int( onosPort2 ) == int( port1 ) ):
2296 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002297 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002298 main.log.warn(
2299 'The port numbers do not match for ' +
2300 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002301 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002302 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002303 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002304 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002305 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002306 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04002307 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002308 if not firstDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002309 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002310 'ONOS does not have the link %s/%s -> %s/%s' %
2311 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002312 if not secondDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002313 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002314 'ONOS does not have the link %s/%s -> %s/%s' %
2315 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002316 linkResults = linkResults and firstDir and secondDir
2317 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002318
Jon Hallafa8a472015-06-12 14:02:42 -07002319 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08002320 """
Jon Hallafa8a472015-06-12 14:02:42 -07002321 Compare mn and onos Hosts.
2322 Since Mininet hosts are quiet, ONOS will only know of them when they
2323 speak. For this reason, we will only check that the hosts in ONOS
2324 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08002325
Jon Hallafa8a472015-06-12 14:02:42 -07002326 Arguments:
2327 hostsJson: parsed json object from the onos hosts api
2328 Returns:
2329 """
Jon Hallff6b4b22015-02-23 09:25:15 -08002330 import json
2331 hostResults = main.TRUE
Jon Hallff6b4b22015-02-23 09:25:15 -08002332 for onosHost in hostsJson:
2333 onosMAC = onosHost[ 'mac' ].lower()
2334 match = False
Jon Halld80cc142015-07-06 13:36:05 -07002335 for mnHost, info in hosts.iteritems():
2336 for mnIntf in info[ 'interfaces' ]:
2337 if onosMAC == mnIntf[ 'mac' ].lower():
Jon Hallff6b4b22015-02-23 09:25:15 -08002338 match = True
2339 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002340 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002341 pass # all is well
2342 else:
2343 # misssing ip
Jon Halld80cc142015-07-06 13:36:05 -07002344 main.log.error( "ONOS host " +
2345 onosHost[ 'id' ] +
2346 " has a different IP(" +
Jon Hallafa8a472015-06-12 14:02:42 -07002347 str( onosHost[ 'ipAddresses' ] ) +
2348 ") than the Mininet host(" +
Jon Halld80cc142015-07-06 13:36:05 -07002349 str( ip ) +
2350 ")." )
Jon Hallff6b4b22015-02-23 09:25:15 -08002351 output = json.dumps(
Jon Halld80cc142015-07-06 13:36:05 -07002352 onosHost,
2353 sort_keys=True,
2354 indent=4,
2355 separators=( ',', ': ' ) )
Jon Hallff6b4b22015-02-23 09:25:15 -08002356 main.log.info( output )
2357 hostResults = main.FALSE
2358 if not match:
2359 hostResults = main.FALSE
2360 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2361 "corresponding Mininet host." )
2362 output = json.dumps( onosHost,
2363 sort_keys=True,
2364 indent=4,
2365 separators=( ',', ': ' ) )
2366 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002367 return hostResults
2368
Jon Hallafa8a472015-06-12 14:02:42 -07002369 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002370 """
2371 Returns a list of all hosts
2372 Don't ask questions just use it"""
2373 self.handle.sendline( "" )
2374 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002375
Jon Hall7eb38402015-01-08 17:19:54 -08002376 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2377 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002378
kelvin-onlabd3b64892015-01-20 13:26:24 -08002379 handlePy = self.handle.before
2380 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2381 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002382
Jon Hall7eb38402015-01-08 17:19:54 -08002383 self.handle.sendline( "" )
2384 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002385
kelvin-onlabd3b64892015-01-20 13:26:24 -08002386 hostStr = handlePy.replace( "]", "" )
2387 hostStr = hostStr.replace( "'", "" )
2388 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002389 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002390 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002391
kelvin-onlabd3b64892015-01-20 13:26:24 -08002392 return hostList
adminbae64d82013-08-01 10:50:15 -07002393
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002394 def getSwitch( self ):
2395 """
2396 Returns a list of all switches
2397 Again, don't ask question just use it...
2398 """
2399 # get host list...
2400 hostList = self.getHosts()
2401 # Make host set
2402 hostSet = set( hostList )
2403
2404 # Getting all the nodes in mininet
2405 self.handle.sendline( "" )
2406 self.handle.expect( "mininet>" )
2407
2408 self.handle.sendline( "py [ node.name for node in net.values() ]" )
2409 self.handle.expect( "mininet>" )
2410
2411 handlePy = self.handle.before
2412 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2413 handlePy = handlePy.rstrip()
2414
2415 self.handle.sendline( "" )
2416 self.handle.expect( "mininet>" )
2417
2418 nodesStr = handlePy.replace( "]", "" )
2419 nodesStr = nodesStr.replace( "'", "" )
2420 nodesStr = nodesStr.replace( "[", "" )
2421 nodesStr = nodesStr.replace( " ", "" )
2422 nodesList = nodesStr.split( "," )
2423
2424 nodesSet = set( nodesList )
2425 # discarding default controller(s) node
2426 nodesSet.discard( 'c0' )
2427 nodesSet.discard( 'c1' )
2428 nodesSet.discard( 'c2' )
2429
2430 switchSet = nodesSet - hostSet
2431 switchList = list( switchSet )
2432
2433 return switchList
2434
Jon Hall7eb38402015-01-08 17:19:54 -08002435 def update( self ):
2436 """
2437 updates the port address and status information for
2438 each port in mn"""
2439 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002440 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002441 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002442 self.handle.sendline( "" )
2443 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002444
Jon Hall7eb38402015-01-08 17:19:54 -08002445 self.handle.sendline( "update" )
2446 self.handle.expect( "update" )
2447 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002448
Jon Hall7eb38402015-01-08 17:19:54 -08002449 self.handle.sendline( "" )
2450 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002451
Jon Hallb1290e82014-11-18 16:17:48 -05002452 return main.TRUE
2453 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002454 main.log.error( self.name + ": EOF exception found" )
2455 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002456 main.cleanup()
2457 main.exit()
2458
Jon Halld80cc142015-07-06 13:36:05 -07002459 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07002460 """
2461 Add vlan tag to a host.
2462 Dependencies:
2463 This class depends on the "vlan" package
2464 $ sudo apt-get install vlan
2465 Configuration:
2466 Load the 8021q module into the kernel
2467 $sudo modprobe 8021q
2468
2469 To make this setup permanent:
2470 $ sudo su -c 'echo "8021q" >> /etc/modules'
2471 """
2472 if self.handle:
2473 try:
Jon Halld80cc142015-07-06 13:36:05 -07002474 # get the ip address of the host
2475 main.log.info( "Get the ip address of the host" )
2476 ipaddr = self.getIPAddress( host )
2477 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07002478
Jon Halld80cc142015-07-06 13:36:05 -07002479 # remove IP from interface intf
2480 # Ex: h1 ifconfig h1-eth0 inet 0
2481 main.log.info( "Remove IP from interface " )
2482 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2483 self.handle.sendline( cmd2 )
2484 self.handle.expect( "mininet>" )
2485 response = self.handle.before
2486 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002487
Jon Halld80cc142015-07-06 13:36:05 -07002488 # create VLAN interface
2489 # Ex: h1 vconfig add h1-eth0 100
2490 main.log.info( "Create Vlan" )
2491 cmd3 = host + " vconfig add " + intf + " " + vlan
2492 self.handle.sendline( cmd3 )
2493 self.handle.expect( "mininet>" )
2494 response = self.handle.before
2495 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002496
Jon Halld80cc142015-07-06 13:36:05 -07002497 # assign the host's IP to the VLAN interface
2498 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2499 main.log.info( "Assign the host IP to the vlan interface" )
2500 vintf = intf + "." + vlan
2501 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2502 self.handle.sendline( cmd4 )
2503 self.handle.expect( "mininet>" )
2504 response = self.handle.before
2505 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002506
2507 return main.TRUE
2508 except pexpect.EOF:
2509 main.log.error( self.name + ": EOF exception found" )
2510 main.log.error( self.name + ": " + self.handle.before )
2511 return main.FALSE
2512
adminbae64d82013-08-01 10:50:15 -07002513if __name__ != "__main__":
2514 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002515 sys.modules[ __name__ ] = MininetCliDriver()