blob: b321492c73ae63b48214f907a6e7a2e4cce22200 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
Jon Hallbe6dfc42015-01-12 17:37:25 -080021MininetCliDriver is the basic driver which will handle the Mininet functions
22
23Some functions rely on a modified version of Mininet. These functions
24should all be noted in the comments. To get this MN version run these commands
25from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080026 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080027 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080028 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git pull
30
Jon Hall272a4db2015-01-12 17:43:48 -080031
32 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080033changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070034import pexpect
adminbae64d82013-08-01 10:50:15 -070035import re
36import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070037import types
kelvin-onlaba4074292015-07-09 15:19:49 -070038import os
Jon Hall1ccf82c2014-10-15 14:55:16 -040039from math import pow
adminbae64d82013-08-01 10:50:15 -070040from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070041
Jon Hall7eb38402015-01-08 17:19:54 -080042
kelvin-onlab50907142015-04-01 13:37:45 -070043class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080044
45 """
46 MininetCliDriver is the basic driver which will handle
47 the Mininet functions"""
48 def __init__( self ):
49 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070050 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080051 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080052 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070053 self.flag = 0
54
Jon Hall7eb38402015-01-08 17:19:54 -080055 def connect( self, **connectargs ):
56 """
57 Here the main is the TestON instance after creating
58 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080059 try:
60 for key in connectargs:
61 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080062
kelvin-onlaba1484582015-02-02 15:46:20 -080063 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070064
65 try:
66 if os.getenv( str( self.ip_address ) ) != None:
67 self.ip_address = os.getenv( str( self.ip_address ) )
68 else:
69 main.log.info( self.name +
70 ": Trying to connect to " +
71 self.ip_address )
72
73 except KeyError:
74 main.log.info( "Invalid host name," +
75 " connecting to local host instead" )
76 self.ip_address = 'localhost'
77 except Exception as inst:
78 main.log.error( "Uncaught exception: " + str( inst ) )
79
kelvin-onlaba1484582015-02-02 15:46:20 -080080 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070081 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080082 self ).connect(
83 user_name=self.user_name,
84 ip_address=self.ip_address,
85 port=None,
86 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080087
kelvin-onlaba1484582015-02-02 15:46:20 -080088 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080089 main.log.info( "Connection successful to the host " +
90 self.user_name +
91 "@" +
92 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080093 return main.TRUE
94 else:
95 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080096 self.user_name +
97 "@" +
98 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080099 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800100 return main.FALSE
101 except pexpect.EOF:
102 main.log.error( self.name + ": EOF exception found" )
103 main.log.error( self.name + ": " + self.handle.before )
104 main.cleanup()
105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800106 except Exception:
107 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800108 main.cleanup()
109 main.exit()
110
kelvin-onlab10e8d392015-06-03 13:53:45 -0700111 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800112 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700113 Description:
114 Starts Mininet accepts a topology(.py) file and/or an optional
115 argument, to start the mininet, as a parameter.
116 Can also send regular mininet command to load up desired topology.
117 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
118 Options:
119 topoFile = file path for topology file (.py)
120 args = extra option added when starting the topology from the file
121 mnCmd = Mininet command use to start topology
122 Returns:
123 main.TRUE if the mininet starts successfully, main.FALSE
124 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800125 """
Jon Hall7eb38402015-01-08 17:19:54 -0800126 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700127 # make sure old networks are cleaned up
128 main.log.info( self.name +
129 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800130 self.handle.sendline( "sudo mn -c" )
131 i = self.handle.expect( [ 'password\sfor\s',
132 'Cleanup\scomplete',
133 pexpect.EOF,
134 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800135 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800136 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700137 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800138 main.log.info( self.name + ": Sending sudo password" )
139 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800140 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800141 '\$',
142 pexpect.EOF,
143 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800144 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800145 if i == 1:
146 main.log.info( self.name + ": Clean" )
147 elif i == 2:
148 main.log.error( self.name + ": Connection terminated" )
149 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700150 main.log.error( self.name + ": Something while cleaning " +
151 "Mininet took too long... " )
152 # Craft the string to start mininet
153 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700154 if not mnCmd:
155 if topoFile is None or topoFile == '': # If no file is given
156 main.log.info( self.name + ": building fresh Mininet" )
157 cmdString += "mn "
158 if args is None or args == '':
159 # If no args given, use args from .topo file
160 args = self.options[ 'arg1' ] +\
Jon Halld80cc142015-07-06 13:36:05 -0700161 " " + self.options[ 'arg2' ] +\
162 " --mac --controller " +\
163 self.options[ 'controller' ] + " " +\
164 self.options[ 'arg3' ]
kelvin-onlab10e8d392015-06-03 13:53:45 -0700165 else: # else only use given args
166 pass
167 # TODO: allow use of topo args and method args?
168 else: # Use given topology file
Jon Halld80cc142015-07-06 13:36:05 -0700169 main.log.info(
170 "Starting Mininet from topo file " +
171 topoFile )
kelvin-onlab10e8d392015-06-03 13:53:45 -0700172 cmdString += topoFile + " "
173 if args is None:
174 args = ''
175 # TODO: allow use of args from .topo file?
176 cmdString += args
177 else:
178 main.log.info( "Starting Mininet topology using '" + mnCmd +
179 "' command" )
180 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700181 # Send the command and check if network started
182 self.handle.sendline( "" )
183 self.handle.expect( '\$' )
184 main.log.info( "Sending '" + cmdString + "' to " + self.name )
185 self.handle.sendline( cmdString )
186 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800187 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700188 'Exception',
189 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800190 pexpect.EOF,
191 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700192 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800193 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700194 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800195 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800196 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700197 response = str( self.handle.before +
198 self.handle.after )
199 self.handle.expect( '\$' )
200 response += str( self.handle.before +
Jon Halld80cc142015-07-06 13:36:05 -0700201 self.handle.after )
Jon Hall689d8e42015-04-03 13:59:24 -0700202 main.log.error(
203 self.name +
204 ": Launching Mininet failed: " + response )
205 return main.FALSE
206 elif i == 2:
207 self.handle.expect( [ "\n",
208 pexpect.EOF,
209 pexpect.TIMEOUT ],
210 timeout )
211 main.log.info( self.handle.before )
212 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800213 main.log.error( self.name + ": Connection timeout" )
214 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700215 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800216 main.log.error(
217 self.name +
218 ": Something took too long... " )
219 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700220 # Why did we hit this part?
221 main.log.error( "startNet did not return correctly" )
222 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800223 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700224 main.log.error( self.name + ": Connection failed to the host " +
225 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800226 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700227 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800228
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800229 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400230 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800231 # In tree topology, if fanout arg is not given, by default it is 2
232 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400233 fanout = 2
234 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500235 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800236 while( k <= depth - 1 ):
237 count = count + pow( fanout, k )
238 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800240 while( k <= depth - 2 ):
241 # depth-2 gives you only core links and not considering
242 # edge links as seen by ONOS. If all the links including
243 # edge links are required, do depth-1
244 count = count + pow( fanout, k )
245 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800247 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800249
Jon Hall7eb38402015-01-08 17:19:54 -0800250 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800252 # by default it is 1
253 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400254 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 numSwitches = depth
256 numHostsPerSw = fanout
257 totalNumHosts = numSwitches * numHostsPerSw
258 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800259 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800261 topoDict = { "num_switches": int( numSwitches ),
262 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400263 return topoDict
264
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700266 """
267 Calculate the number of switches and links in a topo."""
268 # TODO: combine this function and numSwitchesNlinks
269 argList = self.options[ 'arg1' ].split( "," )
270 topoArgList = argList[ 0 ].split( " " )
271 argList = map( int, argList[ 1: ] )
272 topoArgList = topoArgList[ 1: ] + argList
273
274 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400275 return topoDict
276
Jon Halld80cc142015-07-06 13:36:05 -0700277 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800278 """
279 Verifies the reachability of the hosts using pingall command.
280 Optional parameter timeout allows you to specify how long to
281 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700282 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700283 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700284 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700285 ping
286 acceptableFailed - Set the number of acceptable failed pings for the
287 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800288 Returns:
289 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700290 otherwise main.FALSE
291 """
292 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700293 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700294 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700295 if self.handle:
296 main.log.info(
297 self.name +
298 ": Checking reachabilty to the hosts using pingall" )
299 response = ""
300 failedPings = 0
301 returnValue = main.TRUE
302 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700303 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700304 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700305 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700306 pexpect.EOF,
307 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700308 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700309 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700310 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700311 response += self.handle.before
312 break
313 elif i == 1:
314 response += self.handle.before + self.handle.after
315 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700316 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700317 returnValue = main.FALSE
318 if shortCircuit:
319 main.log.error( self.name +
320 ": Aborting pingall - "
321 + str( failedPings ) +
322 " pings failed" )
323 break
Jon Hall390696c2015-05-05 17:13:41 -0700324 if ( time.time() - startTime ) > timeout:
325 returnValue = main.FALSE
326 main.log.error( self.name +
327 ": Aborting pingall - " +
328 "Function took too long " )
329 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700330 elif i == 2:
331 main.log.error( self.name +
332 ": EOF exception found" )
333 main.log.error( self.name + ": " +
334 self.handle.before )
335 main.cleanup()
336 main.exit()
337 elif i == 3:
338 response += self.handle.before
339 main.log.error( self.name +
340 ": TIMEOUT exception found" )
341 main.log.error( self.name +
342 ": " +
343 str( response ) )
344 # NOTE: Send ctrl-c to make sure pingall is done
345 self.handle.sendline( "\x03" )
346 self.handle.expect( "Interrupt" )
347 self.handle.expect( "mininet>" )
348 break
349 pattern = "Results\:"
350 main.log.info( "Pingall output: " + str( response ) )
351 if re.search( pattern, response ):
352 main.log.info( self.name + ": Pingall finished with "
353 + str( failedPings ) + " failed pings" )
354 return returnValue
355 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700356 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700357 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700358 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700359 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700360 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700361 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700362 main.log.error( self.name + ": Connection failed to the host" )
363 main.cleanup()
364 main.exit()
365 except pexpect.TIMEOUT:
366 if response:
367 main.log.info( "Pingall output: " + str( response ) )
368 main.log.error( self.name + ": pexpect.TIMEOUT found" )
369 return main.FALSE
370 except pexpect.EOF:
371 main.log.error( self.name + ": EOF exception found" )
372 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500373 main.cleanup()
374 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700375
Jon Hall7eb38402015-01-08 17:19:54 -0800376 def fpingHost( self, **pingParams ):
377 """
378 Uses the fping package for faster pinging...
379 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800380 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800381 command = args[ "SRC" ] + \
382 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
383 self.handle.sendline( command )
384 self.handle.expect(
385 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
386 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
387 response = self.handle.before
388 if re.search( ":\s-", response ):
389 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700390 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800391 elif re.search( ":\s\d{1,2}\.\d\d", response ):
392 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700393 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800394 main.log.info( self.name + ": Install fping on mininet machine... " )
395 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700396 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800397
Hari Krishna9592fc82015-07-31 15:11:15 -0700398 def pingallHosts( self, hostList ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400399 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700400 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700401
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400402 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700403 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700404
405 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700407
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400408 Returns main.FALSE if one or more of hosts specified
409 cannot reach each other"""
Hari Krishna9592fc82015-07-31 15:11:15 -0700410
411 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400412
413 try:
414 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700415
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400416 isReachable = main.TRUE
417
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400418 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700419 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400420 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700421 pingList = hostList[ :listIndex ] + \
422 hostList[ ( listIndex + 1 ): ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700423
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400424 for temp in pingList:
425 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700426 pingCmd = str( host ) + cmd + str( temp )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400427 self.handle.sendline( pingCmd )
428 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
429 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
430 response = self.handle.before
431 if re.search( ',\s0\%\spacket\sloss', response ):
Jon Halld80cc142015-07-06 13:36:05 -0700432 main.log.info( str( host ) + " -> " + str( temp ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400433 else:
Jon Halld80cc142015-07-06 13:36:05 -0700434 main.log.info(
435 str( host ) + " -> X (" + str( temp ) + ") "
436 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400437 # One of the host to host pair is unreachable
438 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400439
kelvin-onlab2ff57022015-05-29 10:48:51 -0700440 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400441
442 except pexpect.EOF:
443 main.log.error( self.name + ": EOF exception found" )
444 main.log.error( self.name + ": " + self.handle.before )
445 main.cleanup()
446 main.exit()
447
Hari Krishna9592fc82015-07-31 15:11:15 -0700448 def pingIpv6Hosts(self, hostList, prefix='1000::')
449 """
450 IPv6 ping all hosts in hostList. If no prefix passed this will use
451 default prefix of 1000::
452
453 Returns main.TRUE if all hosts specified can reach each other
454
455 Returns main.FALSE if one or more of hosts specified cannot reach each other
456 """
457 try:
458 main.log.info( "Testing reachability between specified IPv6 hosts" )
459 isReachable = main.TRUE
460 cmd = " ping6 -c 1 -i 1 -W 8 "
461 for host in hostList:
462 listIndex = hostList.index( host )
463 # List of hosts to ping other than itself
464 pingList = hostList[ :listIndex ] + \
465 hostList[ ( listIndex + 1 ): ]
466
467 for temp in pingList:
468 # Current host pings all other hosts specified
469 pingCmd = str( host ) + cmd + prefix + str( temp[1:] )
470 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
471 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
472 response = self.handle.before
473 if re.search( ',\s0\%\spacket\sloss', response ):
474 main.log.info( str( host ) + " -> " + str( temp ) )
475 else:
476 main.log.info(
477 str( host ) + " -> X (" + str( temp ) + ") "
478 " Destination Unreachable" )
479 main.log.error( "Response from Mininet: " + str( response ) )
480 # One of the host to host pair is unreachable
481 isReachable = main.FALSE
482 return isReachable
483
484 except pexpect.EOF:
485 main.log.error( self.name + ": EOF exception found" )
486 main.log.error( self.name + ": " + self.handle.before )
487 main.cleanup()
488 main.exit()
489
Jon Hall7eb38402015-01-08 17:19:54 -0800490 def pingHost( self, **pingParams ):
491 """
492 Ping from one mininet host to another
493 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800494 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800495 command = args[ "SRC" ] + " ping " + \
496 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700497 try:
Jon Hall61282e32015-03-19 11:34:11 -0700498 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800499 self.handle.sendline( command )
500 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700501 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800502 main.log.error(
503 self.name +
504 ": timeout when waiting for response from mininet" )
505 main.log.error( "response: " + str( self.handle.before ) )
506 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700507 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800508 main.log.error(
509 self.name +
510 ": timeout when waiting for response from mininet" )
511 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700512 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800513 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800514 main.log.error( self.name + ": EOF exception found" )
515 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700516 main.cleanup()
517 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800518 main.log.info( self.name + ": Ping Response: " + response )
519 if re.search( ',\s0\%\spacket\sloss', response ):
520 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800521 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700522 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800523 else:
524 main.log.error(
525 self.name +
526 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800527 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700528 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800529
Jon Hall7eb38402015-01-08 17:19:54 -0800530 def checkIP( self, host ):
531 """
532 Verifies the host's ip configured or not."""
533 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700534 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800535 response = self.execute(
536 cmd=host +
537 " ifconfig",
538 prompt="mininet>",
539 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800540 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800541 main.log.error( self.name + ": EOF exception found" )
542 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700543 main.cleanup()
544 main.exit()
adminbae64d82013-08-01 10:50:15 -0700545
Jon Hall7eb38402015-01-08 17:19:54 -0800546 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800547 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
548 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
549 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
550 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
551 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800552 # pattern = "inet addr:10.0.0.6"
553 if re.search( pattern, response ):
554 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700555 return main.TRUE
556 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800557 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700558 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800559 else:
560 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800561
Jon Hall7eb38402015-01-08 17:19:54 -0800562 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800563 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700564 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800565 response = self.execute(
566 cmd="h1 /usr/sbin/sshd -D&",
567 prompt="mininet>",
568 timeout=10 )
569 response = self.execute(
570 cmd="h4 /usr/sbin/sshd -D&",
571 prompt="mininet>",
572 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700573 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800574 vars( self )[ key ] = connectargs[ key ]
575 response = self.execute(
576 cmd="xterm h1 h4 ",
577 prompt="mininet>",
578 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800579 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800580 main.log.error( self.name + ": EOF exception found" )
581 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700582 main.cleanup()
583 main.exit()
adminbae64d82013-08-01 10:50:15 -0700584 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800585 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700586 if self.flag == 0:
587 self.flag = 1
588 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800589 else:
adminbae64d82013-08-01 10:50:15 -0700590 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800591
kelvin-onlaba1484582015-02-02 15:46:20 -0800592 def moveHost( self, host, oldSw, newSw, ):
593 """
594 Moves a host from one switch to another on the fly
595 Note: The intf between host and oldSw when detached
596 using detach(), will still show up in the 'net'
597 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700598 ( which is correct behavior since the interfaces
599 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800600 """
601 if self.handle:
602 try:
603 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700604 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800605 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800606 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800607 response = self.execute( cmd=cmd,
608 prompt="mininet>",
609 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700610
kelvin-onlaba1484582015-02-02 15:46:20 -0800611 # Determine hostintf and Oldswitchintf
612 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800613 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800614 print "cmd2= ", cmd
615 self.handle.sendline( cmd )
616 self.handle.expect( "mininet>" )
617
shahshreya73537862015-02-11 15:15:24 -0800618 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800619 cmd = "px ipaddr = hintf.IP()"
620 print "cmd3= ", cmd
621 self.handle.sendline( cmd )
622 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800623
624 cmd = "px macaddr = hintf.MAC()"
625 print "cmd3= ", cmd
626 self.handle.sendline( cmd )
627 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700628
kelvin-onlaba1484582015-02-02 15:46:20 -0800629 # Detach interface between oldSw-host
630 cmd = "px " + oldSw + ".detach( sintf )"
631 print "cmd4= ", cmd
632 self.handle.sendline( cmd )
633 self.handle.expect( "mininet>" )
634
635 # Add link between host-newSw
636 cmd = "py net.addLink(" + host + "," + newSw + ")"
637 print "cmd5= ", cmd
638 self.handle.sendline( cmd )
639 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700640
kelvin-onlaba1484582015-02-02 15:46:20 -0800641 # Determine hostintf and Newswitchintf
642 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800643 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800644 print "cmd6= ", cmd
645 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700646 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800647
648 # Attach interface between newSw-host
649 cmd = "px " + newSw + ".attach( sintf )"
650 print "cmd3= ", cmd
651 self.handle.sendline( cmd )
652 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700653
kelvin-onlaba1484582015-02-02 15:46:20 -0800654 # Set ipaddress of the host-newSw interface
655 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
656 print "cmd7 = ", cmd
657 self.handle.sendline( cmd )
658 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800659
660 # Set macaddress of the host-newSw interface
661 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
662 print "cmd8 = ", cmd
663 self.handle.sendline( cmd )
664 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700665
kelvin-onlaba1484582015-02-02 15:46:20 -0800666 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800667 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800668 self.handle.sendline( cmd )
669 self.handle.expect( "mininet>" )
670 print "output = ", self.handle.before
671
672 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800673 cmd = host + " ifconfig"
674 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800675 self.handle.sendline( cmd )
676 self.handle.expect( "mininet>" )
677 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700678
kelvin-onlaba1484582015-02-02 15:46:20 -0800679 return main.TRUE
680 except pexpect.EOF:
681 main.log.error( self.name + ": EOF exception found" )
682 main.log.error( self.name + ": " + self.handle.before )
683 return main.FALSE
684
Jon Hall7eb38402015-01-08 17:19:54 -0800685 def changeIP( self, host, intf, newIP, newNetmask ):
686 """
687 Changes the ip address of a host on the fly
688 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800689 if self.handle:
690 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800691 cmd = host + " ifconfig " + intf + " " + \
692 newIP + " " + 'netmask' + " " + newNetmask
693 self.handle.sendline( cmd )
694 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800695 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800696 main.log.info( "response = " + response )
697 main.log.info(
698 "Ip of host " +
699 host +
700 " changed to new IP " +
701 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800702 return main.TRUE
703 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800704 main.log.error( self.name + ": EOF exception found" )
705 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800706 return main.FALSE
707
Jon Hall7eb38402015-01-08 17:19:54 -0800708 def changeDefaultGateway( self, host, newGW ):
709 """
710 Changes the default gateway of a host
711 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800712 if self.handle:
713 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800714 cmd = host + " route add default gw " + newGW
715 self.handle.sendline( cmd )
716 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800717 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800718 main.log.info( "response = " + response )
719 main.log.info(
720 "Default gateway of host " +
721 host +
722 " changed to " +
723 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800724 return main.TRUE
725 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800726 main.log.error( self.name + ": EOF exception found" )
727 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800728 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800729
Jon Hall7eb38402015-01-08 17:19:54 -0800730 def addStaticMACAddress( self, host, GW, macaddr ):
731 """
Jon Hallefbd9792015-03-05 16:11:36 -0800732 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800733 if self.handle:
734 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800735 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
736 cmd = host + " arp -s " + GW + " " + macaddr
737 self.handle.sendline( cmd )
738 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800739 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800740 main.log.info( "response = " + response )
741 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800742 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800743 GW +
744 " changed to " +
745 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800746 return main.TRUE
747 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800748 main.log.error( self.name + ": EOF exception found" )
749 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800750 return main.FALSE
751
Jon Hall7eb38402015-01-08 17:19:54 -0800752 def verifyStaticGWandMAC( self, host ):
753 """
754 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800755 if self.handle:
756 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800757 # h1 arp -an
758 cmd = host + " arp -an "
759 self.handle.sendline( cmd )
760 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800761 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800762 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800763 return main.TRUE
764 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800767 return main.FALSE
768
Jon Hall7eb38402015-01-08 17:19:54 -0800769 def getMacAddress( self, host ):
770 """
771 Verifies the host's ip configured or not."""
772 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700773 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800774 response = self.execute(
775 cmd=host +
776 " ifconfig",
777 prompt="mininet>",
778 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800779 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800780 main.log.error( self.name + ": EOF exception found" )
781 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700782 main.cleanup()
783 main.exit()
adminbae64d82013-08-01 10:50:15 -0700784
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700785 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800786 macAddressSearch = re.search( pattern, response, re.I )
787 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800788 main.log.info(
789 self.name +
790 ": Mac-Address of Host " +
791 host +
792 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800793 macAddress )
794 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700795 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800796 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700797
Jon Hall7eb38402015-01-08 17:19:54 -0800798 def getInterfaceMACAddress( self, host, interface ):
799 """
800 Return the IP address of the interface on the given host"""
801 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700802 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800803 response = self.execute( cmd=host + " ifconfig " + interface,
804 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800805 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800806 main.log.error( self.name + ": EOF exception found" )
807 main.log.error( self.name + ": " + self.handle.before )
808 main.cleanup()
809 main.exit()
810
811 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800812 macAddressSearch = re.search( pattern, response, re.I )
813 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800814 main.log.info( "No mac address found in %s" % response )
815 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800816 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800817 main.log.info(
818 "Mac-Address of " +
819 host +
820 ":" +
821 interface +
822 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 macAddress )
824 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800825 else:
826 main.log.error( "Connection failed to the host" )
827
828 def getIPAddress( self, host ):
829 """
830 Verifies the host's ip configured or not."""
831 if self.handle:
832 try:
833 response = self.execute(
834 cmd=host +
835 " ifconfig",
836 prompt="mininet>",
837 timeout=10 )
838 except pexpect.EOF:
839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700841 main.cleanup()
842 main.exit()
adminbae64d82013-08-01 10:50:15 -0700843
844 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800845 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800846 main.log.info(
847 self.name +
848 ": IP-Address of Host " +
849 host +
850 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800851 ipAddressSearch.group( 1 ) )
852 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800853 else:
854 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800855
Jon Hall7eb38402015-01-08 17:19:54 -0800856 def getSwitchDPID( self, switch ):
857 """
858 return the datapath ID of the switch"""
859 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700860 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700861 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800862 response = self.execute(
863 cmd=cmd,
864 prompt="mininet>",
865 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800866 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800867 main.log.error( self.name + ": EOF exception found" )
868 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700869 main.cleanup()
870 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800871 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800872 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700873 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800874 main.log.info(
875 "Couldn't find DPID for switch %s, found: %s" %
876 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700877 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800878 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700879 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800880 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700881
Jon Hall7eb38402015-01-08 17:19:54 -0800882 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700883 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800884 self.handle.sendline( "" )
885 self.expect( "mininet>" )
886 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700887 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800888 response = self.execute(
889 cmd=cmd,
890 prompt="mininet>",
891 timeout=10 )
892 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700893 response = self.handle.before
894 return response
895 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800896 main.log.error( self.name + ": EOF exception found" )
897 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700898 main.cleanup()
899 main.exit()
900
Jon Hall7eb38402015-01-08 17:19:54 -0800901 def getInterfaces( self, node ):
902 """
903 return information dict about interfaces connected to the node"""
904 if self.handle:
905 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800906 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700907 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700908 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800909 response = self.execute(
910 cmd=cmd,
911 prompt="mininet>",
912 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800913 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800914 main.log.error( self.name + ": EOF exception found" )
915 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700916 main.cleanup()
917 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700918 return response
919 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800920 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700921
Jon Hall7eb38402015-01-08 17:19:54 -0800922 def dump( self ):
923 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700924 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800925 response = self.execute(
926 cmd='dump',
927 prompt='mininet>',
928 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800929 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700932 main.cleanup()
933 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700934 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800935
Jon Hall7eb38402015-01-08 17:19:54 -0800936 def intfs( self ):
937 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700938 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800939 response = self.execute(
940 cmd='intfs',
941 prompt='mininet>',
942 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800943 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700946 main.cleanup()
947 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700948 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800949
Jon Hall7eb38402015-01-08 17:19:54 -0800950 def net( self ):
951 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700952 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800953 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800954 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800955 main.log.error( self.name + ": EOF exception found" )
956 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700957 main.cleanup()
958 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700959 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800960
Jon Hallafa8a472015-06-12 14:02:42 -0700961 def links( self ):
962 main.log.info( self.name + ": List network links" )
963 try:
964 response = self.execute( cmd='links', prompt='mininet>',
965 timeout=10 )
966 except pexpect.EOF:
967 main.log.error( self.name + ": EOF exception found" )
968 main.log.error( self.name + ": " + self.handle.before )
969 main.cleanup()
970 main.exit()
971 return response
972
GlennRC61321f22015-07-16 13:36:54 -0700973 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700974 '''
975 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -0700976
kelvin-onlab7cce9382015-07-17 10:21:03 -0700977 @parm:
978 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
979 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
980 '''
981 for host1 in hosts:
982 for host2 in hosts:
983 if host1 != host2:
984 if self.iperftcp(host1, host2, timeout) == main.FALSE:
985 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
GlennRC61321f22015-07-16 13:36:54 -0700986
987 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700988 '''
989 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
990 are valid.
GlennRC61321f22015-07-16 13:36:54 -0700991
kelvin-onlab7cce9382015-07-17 10:21:03 -0700992 @parm:
993 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
994 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
995 '''
996 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
997 try:
998 # Setup the mininet command
999 cmd1 = 'iperf ' + host1 + " " + host2
1000 self.handle.sendline( cmd1 )
1001 outcome = self.handle.expect( "mininet>", timeout )
1002 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001003
kelvin-onlab7cce9382015-07-17 10:21:03 -07001004 # checks if there are results in the mininet response
1005 if "Results:" in response:
1006 main.log.report(self.name + ": iperf test completed")
1007 # parse the mn results
1008 response = response.split("\r\n")
1009 response = response[len(response)-2]
1010 response = response.split(": ")
1011 response = response[len(response)-1]
1012 response = response.replace("[", "")
1013 response = response.replace("]", "")
1014 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001015
kelvin-onlab7cce9382015-07-17 10:21:03 -07001016 # this is the bandwith two and from the two hosts
1017 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001018
kelvin-onlab7cce9382015-07-17 10:21:03 -07001019 # there should be two elements in the bandwidth list
1020 # ['host1 to host2', 'host2 to host1"]
1021 if len(bandwidth) == 2:
1022 main.log.report(self.name + ": iperf test successful")
1023 return main.TRUE
1024 else:
1025 main.log.error(self.name + ": invalid iperf results")
1026 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001027 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001028 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001029 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001030
GlennRC61321f22015-07-16 13:36:54 -07001031 except pexpect.TIMEOUT:
1032 main.log.error( self.name + ": TIMEOUT exception found")
1033 main.log.error( self.name + ": Exception: Cannot connect to iperf on port 5001" )
1034 return main.FALSE
1035
Jon Hallfbc828e2015-01-06 17:30:19 -08001036 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001037 main.log.error( self.name + ": EOF exception found" )
1038 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001039 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001040 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001041
1042 def iperfudpAll(self, hosts, bandwidth="10M"):
1043 '''
1044 Runs the iperfudp function with a given set of hosts and specified
1045 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001046
GlennRC61321f22015-07-16 13:36:54 -07001047 @param:
1048 bandwidth: the targeted bandwidth, in megabits ('M')
1049 '''
1050 for host1 in hosts:
1051 for host2 in hosts:
1052 if host1 != host2:
1053 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1054 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1055
1056 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1057
kelvin-onlab7cce9382015-07-17 10:21:03 -07001058 '''
1059 Creates an iperf UDP test with a specific bandwidth.
1060 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001061
kelvin-onlab7cce9382015-07-17 10:21:03 -07001062 @param:
1063 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1064 '''
1065 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1066 try:
1067 # setup the mininet command
1068 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1069 self.handle.sendline(cmd)
1070 self.handle.expect("mininet>")
1071 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001072
kelvin-onlab7cce9382015-07-17 10:21:03 -07001073 # check if there are in results in the mininet response
1074 if "Results:" in response:
1075 main.log.report(self.name + ": iperfudp test completed")
1076 # parse the results
1077 response = response.split("\r\n")
1078 response = response[len(response)-2]
1079 response = response.split(": ")
1080 response = response[len(response)-1]
1081 response = response.replace("[", "")
1082 response = response.replace("]", "")
1083 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001084
kelvin-onlab7cce9382015-07-17 10:21:03 -07001085 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001086
kelvin-onlab7cce9382015-07-17 10:21:03 -07001087 # check to see if there are at least three entries
1088 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1089 if len(mnBandwidth) == 3:
1090 # if one entry is blank then something is wrong
1091 for item in mnBandwidth:
1092 if item == "":
1093 main.log.error(self.name + ": Could not parse iperf output")
1094 main.log.error(self.name + ": invalid iperfudp results")
1095 return main.FALSE
1096 # otherwise results are vaild
1097 main.log.report(self.name + ": iperfudp test successful")
1098 return main.TRUE
1099 else:
1100 main.log.error(self.name + ": invalid iperfudp results")
1101 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001102
kelvin-onlab7cce9382015-07-17 10:21:03 -07001103 except pexpect.EOF:
1104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
1106 main.cleanup()
1107 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001108
Jon Hall7eb38402015-01-08 17:19:54 -08001109 def nodes( self ):
1110 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001111 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001112 response = self.execute(
1113 cmd='nodes',
1114 prompt='mininet>',
1115 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001116 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001117 main.log.error( self.name + ": EOF exception found" )
1118 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001119 main.cleanup()
1120 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001121 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001122
Jon Hall7eb38402015-01-08 17:19:54 -08001123 def pingpair( self ):
1124 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001125 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001126 response = self.execute(
1127 cmd='pingpair',
1128 prompt='mininet>',
1129 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001130 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001131 main.log.error( self.name + ": EOF exception found" )
1132 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001133 main.cleanup()
1134 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001135
Jon Hall7eb38402015-01-08 17:19:54 -08001136 if re.search( ',\s0\%\spacket\sloss', response ):
1137 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -07001139 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001140 else:
1141 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -07001143 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001144
Jon Hall7eb38402015-01-08 17:19:54 -08001145 def link( self, **linkargs ):
1146 """
1147 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001148 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001149 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1150 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1151 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1152 main.log.info(
1153 "Bring link between '" +
1154 end1 +
1155 "' and '" +
1156 end2 +
1157 "' '" +
1158 option +
1159 "'" )
1160 command = "link " + \
1161 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001162 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001163 self.handle.sendline( command )
1164 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001165 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001166 main.log.error( self.name + ": EOF exception found" )
1167 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001168 main.cleanup()
1169 main.exit()
adminbae64d82013-08-01 10:50:15 -07001170 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001171
Jon Hall7eb38402015-01-08 17:19:54 -08001172 def yank( self, **yankargs ):
1173 """
1174 yank a mininet switch interface to a host"""
1175 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001176 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001177 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1178 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1179 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001180 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001181 response = self.execute(
1182 cmd=command,
1183 prompt="mininet>",
1184 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001185 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001188 main.cleanup()
1189 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001190 return main.TRUE
1191
Jon Hall7eb38402015-01-08 17:19:54 -08001192 def plug( self, **plugargs ):
1193 """
1194 plug the yanked mininet switch interface to a switch"""
1195 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001196 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001197 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1198 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1199 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001200 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001201 response = self.execute(
1202 cmd=command,
1203 prompt="mininet>",
1204 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001205 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001206 main.log.error( self.name + ": EOF exception found" )
1207 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001208 main.cleanup()
1209 main.exit()
adminbae64d82013-08-01 10:50:15 -07001210 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001211
Jon Hall7eb38402015-01-08 17:19:54 -08001212 def dpctl( self, **dpctlargs ):
1213 """
1214 Run dpctl command on all switches."""
1215 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001216 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001217 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1218 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1219 command = "dpctl " + cmd + " " + str( cmdargs )
1220 try:
1221 response = self.execute(
1222 cmd=command,
1223 prompt="mininet>",
1224 timeout=10 )
1225 except pexpect.EOF:
1226 main.log.error( self.name + ": EOF exception found" )
1227 main.log.error( self.name + ": " + self.handle.before )
1228 main.cleanup()
1229 main.exit()
1230 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001231
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001233 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001234 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 fileInput = path + '/lib/Mininet/INSTALL'
1236 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001237 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001238 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001239 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001240 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001241 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001242 return version
adminbae64d82013-08-01 10:50:15 -07001243
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001245 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001246 Parameters:
1247 sw: The name of an OVS switch. Example "s1"
1248 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001249 The output of the command from the mininet cli
1250 or main.FALSE on timeout"""
1251 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001252 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001253 response = self.execute(
1254 cmd=command,
1255 prompt="mininet>",
1256 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001257 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001258 return response
admin2a9548d2014-06-17 14:08:07 -07001259 else:
1260 return main.FALSE
1261 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001262 main.log.error( self.name + ": EOF exception found" )
1263 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001264 main.cleanup()
1265 main.exit()
adminbae64d82013-08-01 10:50:15 -07001266
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001267 def assignSwController( self, sw, ip, port="6633", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001268 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001269 Description:
1270 Assign switches to the controllers ( for ovs use only )
1271 Required:
1272 sw - Name of the switch. This can be a list or a string.
1273 ip - Ip addresses of controllers. This can be a list or a string.
1274 Optional:
1275 port - ONOS use port 6633, if no list of ports is passed, then
1276 the all the controller will use 6633 as their port number
1277 ptcp - ptcp number, This can be a string or a list that has
1278 the same length as switch. This is optional and not required
1279 when using ovs switches.
1280 NOTE: If switches and ptcp are given in a list type they should have the
1281 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1282 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001283
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001284 Return:
1285 Returns main.TRUE if mininet correctly assigned switches to
1286 controllers, otherwise it will return main.FALSE or an appropriate
1287 exception(s)
1288 """
1289 assignResult = main.TRUE
1290 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001291 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001292 command = "sh ovs-vsctl set-controller "
1293 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001294 try:
1295 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001296 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001297 if isinstance( port, types.StringType ) or \
1298 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001299 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001300 elif isinstance( port, types.ListType ):
1301 main.log.error( self.name + ": Only one controller " +
1302 "assigned and a list of ports has" +
1303 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001304 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001305 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001306 main.log.error( self.name + ": Invalid controller port " +
1307 "number. Please specify correct " +
1308 "controller port" )
1309 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001310
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001311 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001312 if isinstance( port, types.StringType ) or \
1313 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001314 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001315 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1316 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001317 elif isinstance( port, types.ListType ):
1318 if ( len( ip ) != len( port ) ):
1319 main.log.error( self.name + ": Port list = " +
1320 str( len( port ) ) +
1321 "should be the same as controller" +
1322 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001323 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001324 else:
1325 onosIp = ""
1326 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001327 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1328 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001329 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001330 main.log.error( self.name + ": Invalid controller port " +
1331 "number. Please specify correct " +
1332 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001333 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001334 else:
1335 main.log.error( self.name + ": Invalid ip address" )
1336 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001337
1338 if isinstance( sw, types.StringType ):
1339 command += sw + " "
1340 if ptcp:
1341 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001342 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001343 elif isinstance( ptcp, types.ListType ):
1344 main.log.error( self.name + ": Only one switch is " +
1345 "being set and multiple PTCP is " +
1346 "being passed " )
1347 else:
1348 main.log.error( self.name + ": Invalid PTCP" )
1349 ptcp = ""
1350 command += onosIp
1351 commandList.append( command )
1352
1353 elif isinstance( sw, types.ListType ):
1354 if ptcp:
1355 if isinstance( ptcp, types.ListType ):
1356 if len( ptcp ) != len( sw ):
1357 main.log.error( self.name + ": PTCP length = " +
1358 str( len( ptcp ) ) +
1359 " is not the same as switch" +
1360 " length = " +
1361 str( len( sw ) ) )
1362 return main.FALSE
1363 else:
1364 for switch, ptcpNum in zip( sw, ptcp ):
1365 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001366 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001367 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001368 tempCmd += onosIp
1369 commandList.append( tempCmd )
1370 else:
1371 main.log.error( self.name + ": Invalid PTCP" )
1372 return main.FALSE
1373 else:
1374 for switch in sw:
1375 tempCmd = "sh ovs-vsctl set-controller "
1376 tempCmd += switch + " " + onosIp
1377 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001378 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001379 main.log.error( self.name + ": Invalid switch type " )
1380 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001381
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001382 for cmd in commandList:
1383 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001384 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001385 except pexpect.TIMEOUT:
1386 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1387 return main.FALSE
1388 except pexpect.EOF:
1389 main.log.error( self.name + ": EOF exception found" )
1390 main.log.error( self.name + ": " + self.handle.before )
1391 main.cleanup()
1392 main.exit()
1393 return main.TRUE
1394 except Exception:
1395 main.log.exception( self.name + ": Uncaught exception!" )
1396 main.cleanup()
1397 main.exit()
adminbae64d82013-08-01 10:50:15 -07001398
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001400 """
1401 Removes the controller target from sw"""
1402 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001403 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001404 response = self.execute(
1405 cmd=command,
1406 prompt="mininet>",
1407 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001408 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001409 main.log.error( self.name + ": EOF exception found" )
1410 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001411 main.cleanup()
1412 main.exit()
1413 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001414 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001415
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001417 """
Jon Hallb1290e82014-11-18 16:17:48 -05001418 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001419 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001420 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001421 NOTE: cannot currently specify what type of switch
1422 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001423 sw = name of the new switch as a string
1424 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001425 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001426 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001427 """
1428 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001429 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001430 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001431 response = self.execute(
1432 cmd=command,
1433 prompt="mininet>",
1434 timeout=10 )
1435 if re.search( "already exists!", response ):
1436 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001437 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001438 elif re.search( "Error", response ):
1439 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001440 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001441 elif re.search( "usage:", response ):
1442 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001443 return main.FALSE
1444 else:
1445 return main.TRUE
1446 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001447 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001448 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001449 main.cleanup()
1450 main.exit()
1451
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001453 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001454 delete a switch from the mininet topology
1455 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001456 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001457 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001458 sw = name of the switch as a string
1459 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001460 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001461 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001462 response = self.execute(
1463 cmd=command,
1464 prompt="mininet>",
1465 timeout=10 )
1466 if re.search( "no switch named", response ):
1467 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001468 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001469 elif re.search( "Error", response ):
1470 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001471 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001472 elif re.search( "usage:", response ):
1473 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001474 return main.FALSE
1475 else:
1476 return main.TRUE
1477 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001478 main.log.error( self.name + ": EOF exception found" )
1479 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001480 main.cleanup()
1481 main.exit()
1482
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001484 """
1485 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001486 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001487 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001488 NOTE: cannot currently specify what type of link
1489 required params:
1490 node1 = the string node name of the first endpoint of the link
1491 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001492 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001493 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001494 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001495 response = self.execute(
1496 cmd=command,
1497 prompt="mininet>",
1498 timeout=10 )
1499 if re.search( "doesnt exist!", response ):
1500 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001501 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001502 elif re.search( "Error", response ):
1503 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001504 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001505 elif re.search( "usage:", response ):
1506 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001507 return main.FALSE
1508 else:
1509 return main.TRUE
1510 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001511 main.log.error( self.name + ": EOF exception found" )
1512 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001513 main.cleanup()
1514 main.exit()
1515
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001517 """
1518 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001519 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001520 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001521 required params:
1522 node1 = the string node name of the first endpoint of the link
1523 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001524 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001525 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001526 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001527 response = self.execute(
1528 cmd=command,
1529 prompt="mininet>",
1530 timeout=10 )
1531 if re.search( "no node named", response ):
1532 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001533 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001534 elif re.search( "Error", response ):
1535 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001536 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001537 elif re.search( "usage:", response ):
1538 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001539 return main.FALSE
1540 else:
1541 return main.TRUE
1542 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001543 main.log.error( self.name + ": EOF exception found" )
1544 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001545 main.cleanup()
1546 main.exit()
1547
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001549 """
Jon Hallb1290e82014-11-18 16:17:48 -05001550 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001551 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001552 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001553 NOTE: cannot currently specify what type of host
1554 required params:
1555 hostname = the string hostname
1556 optional key-value params
1557 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001558 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001559 """
1560 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001561 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001562 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001563 response = self.execute(
1564 cmd=command,
1565 prompt="mininet>",
1566 timeout=10 )
1567 if re.search( "already exists!", response ):
1568 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001569 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001570 elif re.search( "doesnt exists!", response ):
1571 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001572 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001573 elif re.search( "Error", response ):
1574 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001575 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001576 elif re.search( "usage:", response ):
1577 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001578 return main.FALSE
1579 else:
1580 return main.TRUE
1581 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001582 main.log.error( self.name + ": EOF exception found" )
1583 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001584 main.cleanup()
1585 main.exit()
1586
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001588 """
1589 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001590 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001591 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001592 NOTE: this uses a custom mn function
1593 required params:
1594 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001595 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001596 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001597 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001598 response = self.execute(
1599 cmd=command,
1600 prompt="mininet>",
1601 timeout=10 )
1602 if re.search( "no host named", response ):
1603 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001604 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001605 elif re.search( "Error", response ):
1606 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001607 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001608 elif re.search( "usage:", response ):
1609 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001610 return main.FALSE
1611 else:
1612 return main.TRUE
1613 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001614 main.log.error( self.name + ": EOF exception found" )
1615 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001616 main.cleanup()
1617 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001618
Jon Hall7eb38402015-01-08 17:19:54 -08001619 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001620 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001621 Called at the end of the test to stop the mininet and
1622 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001623 """
Jon Halld80cc142015-07-06 13:36:05 -07001624 self.handle.sendline( '' )
Jon Halld61331b2015-02-17 16:35:47 -08001625 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -07001626 timeout=2 )
Jon Hall390696c2015-05-05 17:13:41 -07001627 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001628 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001629 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001630 elif i == 1:
1631 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001632 # print "Disconnecting Mininet"
1633 if self.handle:
1634 self.handle.sendline( "exit" )
1635 self.handle.expect( "exit" )
1636 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001637 else:
1638 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001639 return response
1640
Jon Halld80cc142015-07-06 13:36:05 -07001641 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001642 """
Jon Hall21270ac2015-02-16 17:59:55 -08001643 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001644 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001645 main.FALSE if the pexpect handle does not exist.
1646
Jon Halld61331b2015-02-17 16:35:47 -08001647 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001648 """
Jon Halld61331b2015-02-17 16:35:47 -08001649 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001650 response = ''
1651 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001652 try:
Jon Halld80cc142015-07-06 13:36:05 -07001653 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08001654 i = self.handle.expect( [ 'mininet>',
1655 '\$',
1656 pexpect.EOF,
1657 pexpect.TIMEOUT ],
1658 timeout )
1659 if i == 0:
1660 main.log.info( "Exiting mininet..." )
Jon Hall7eb38402015-01-08 17:19:54 -08001661 response = self.execute(
1662 cmd="exit",
1663 prompt="(.*)",
1664 timeout=120 )
Jon Halld80cc142015-07-06 13:36:05 -07001665 main.log.info( self.name + ": Stopped" )
Jon Hall7eb38402015-01-08 17:19:54 -08001666 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001667 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001668
kelvin-onlab56a3f462015-02-06 14:04:43 -08001669 if i == 1:
1670 main.log.info( " Mininet trying to exit while not " +
1671 "in the mininet prompt" )
1672 elif i == 2:
1673 main.log.error( "Something went wrong exiting mininet" )
1674 elif i == 3: # timeout
1675 main.log.error( "Something went wrong exiting mininet " +
1676 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07001677
Hari Krishnab35c6d02015-03-18 11:13:51 -07001678 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07001679 self.handle.sendline( "" )
1680 self.handle.expect( '\$' )
1681 self.handle.sendline(
1682 "sudo kill -9 \`ps -ef | grep \"" +
1683 fileName +
1684 "\" | grep -v grep | awk '{print $2}'\`" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001685 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001686 main.log.error( self.name + ": EOF exception found" )
1687 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001688 main.cleanup()
1689 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001690 else:
1691 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001692 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001693 return response
1694
kelvin-onlabf0594d72015-05-19 17:25:12 -07001695 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001696 """
1697 Description:
1698 Sends arp message from mininet host for hosts discovery
1699 Required:
1700 host - hosts name
1701 Optional:
1702 ip - ip address that does not exist in the network so there would
1703 be no reply.
1704 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001705 if ethDevice:
1706 ethDevice = '-I ' + ethDevice + ' '
Jon Halld80cc142015-07-06 13:36:05 -07001707 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001708 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001709 main.log.warn( "Sending: " + cmd )
1710 self.handle.sendline( cmd )
1711 response = self.handle.before
1712 self.handle.sendline( "" )
1713 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001714 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001715
1716 except pexpect.EOF:
1717 main.log.error( self.name + ": EOF exception found" )
1718 main.log.error( self.name + ": " + self.handle.before )
1719 main.cleanup()
1720 main.exit()
admin07529932013-11-22 14:58:28 -08001721
Jon Hall7eb38402015-01-08 17:19:54 -08001722 def decToHex( self, num ):
1723 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001724
Jon Hall7eb38402015-01-08 17:19:54 -08001725 def getSwitchFlowCount( self, switch ):
1726 """
1727 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001728 if self.handle:
1729 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1730 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001731 response = self.execute(
1732 cmd=cmd,
1733 prompt="mininet>",
1734 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001735 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001736 main.log.error( self.name + ": EOF exception found" )
1737 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001738 main.cleanup()
1739 main.exit()
1740 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001741 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001742 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001743 main.log.info(
1744 "Couldn't find flows on switch %s, found: %s" %
1745 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001746 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001747 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001748 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001749 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001750
kelvin-onlabd3b64892015-01-20 13:26:24 -08001751 def checkFlows( self, sw, dumpFormat=None ):
1752 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001753 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001754 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001755 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001756 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001757 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001758 response = self.execute(
1759 cmd=command,
1760 prompt="mininet>",
1761 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001762 return response
1763 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001764 main.log.error( self.name + ": EOF exception found" )
1765 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001766 main.cleanup()
1767 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001768
Jon Hall9043c902015-07-30 14:23:44 -07001769 def getFlowTable( self, protoVersion, sw ):
1770 """
1771 Returns certain fields of an OVS flow table. Will force output to
1772 either OF 1.0 or 1.3 format for consistency.
1773
1774 TODO add option to look at cookies. ignoring them for now
1775
1776 NOTE: Use format to force consistent flow table output across
1777 versions
1778 """
1779 try:
1780 self.handle.sendline( "" )
1781 self.handle.expect( "mininet>" )
1782 command = "sh ovs-ofctl dump-flows " + sw
1783 if protoVersion == 1.0:
1784 command += " -F OpenFlow10-table_id | awk '{OFS=\",\" ;" +\
1785 " print $1 $3 $6 $7 $8}' | "
1786 elif protoVersion == 1.3:
1787 command += " -O OpenFlow13 | awk '{OFS=\",\" ;" +\
1788 " print $1 $3 $6 $7}' | "
1789 else:
1790 main.log.error(
1791 "Unknown protoVersion in getFlowTable(). given: (" +
1792 str( type( protoVersion ) ) +
1793 ") '" + str( protoVersion ) + "'" )
1794 return None
1795 command += "cut -d ',' -f 2- | sort -n -k1 -r"
1796 self.handle.sendline( command )
1797 self.handle.expect( "sort" )
1798 self.handle.expect( "OFPST_FLOW" )
1799 response = self.handle.before
1800 return response
1801 except pexpect.EOF:
1802 main.log.error( self.name + ": EOF exception found" )
1803 main.log.error( self.name + ": " + self.handle.before )
1804 main.cleanup()
1805 main.exit()
1806 except pexpect.TIMEOUT:
1807 main.log.exception( self.name + ": Timeout exception: " )
1808 return None
1809
1810 def flowComp( self, flow1, flow2 ):
1811 if flow1 == flow2:
1812 return main.TRUE
1813 else:
1814 main.log.info( "Flow tables do not match, printing tables:" )
1815 main.log.info( "Flow Table 1:" )
1816 main.log.info( flow1 )
1817 main.log.info( "Flow Table 2:" )
1818 main.log.info( flow2 )
1819 return main.FALSE
1820
kelvin-onlabd3b64892015-01-20 13:26:24 -08001821 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001822 """
Jon Hallefbd9792015-03-05 16:11:36 -08001823 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001824 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001825 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001826 self.handle.sendline( "" )
1827 self.handle.expect( "mininet>" )
1828 self.handle.sendline(
1829 "sh sudo tcpdump -n -i " +
1830 intf +
1831 " " +
1832 port +
1833 " -w " +
1834 filename.strip() +
1835 " &" )
1836 self.handle.sendline( "" )
1837 i = self.handle.expect( [ 'No\ssuch\device',
1838 'listening\son',
1839 pexpect.TIMEOUT,
1840 "mininet>" ],
1841 timeout=10 )
1842 main.log.warn( self.handle.before + self.handle.after )
1843 self.handle.sendline( "" )
1844 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001845 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001846 main.log.error(
1847 self.name +
1848 ": tcpdump - No such device exists. " +
1849 "tcpdump attempted on: " +
1850 intf )
admin2a9548d2014-06-17 14:08:07 -07001851 return main.FALSE
1852 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001853 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001854 return main.TRUE
1855 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001856 main.log.error(
1857 self.name +
1858 ": tcpdump command timed out! Check interface name," +
1859 " given interface was: " +
1860 intf )
admin2a9548d2014-06-17 14:08:07 -07001861 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001862 elif i == 3:
1863 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001864 return main.TRUE
1865 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001866 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001867 return main.FALSE
1868 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001869 main.log.error( self.name + ": EOF exception found" )
1870 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001871 main.cleanup()
1872 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001873 except Exception:
1874 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001875 main.cleanup()
1876 main.exit()
1877
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001879 """
1880 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001881 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001882 self.handle.sendline( "sh sudo pkill tcpdump" )
1883 self.handle.expect( "mininet>" )
1884 self.handle.sendline( "" )
1885 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001886 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001887 main.log.error( self.name + ": EOF exception found" )
1888 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001889 main.cleanup()
1890 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001891 except Exception:
1892 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001893 main.cleanup()
1894 main.exit()
1895
Jon Halld80cc142015-07-06 13:36:05 -07001896 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001897 """
1898 Read ports from a Mininet switch.
1899
1900 Returns a json structure containing information about the
1901 ports of the given switch.
1902 """
1903 response = self.getInterfaces( nodeName )
1904 # TODO: Sanity check on response. log if no such switch exists
1905 ports = []
1906 for line in response.split( "\n" ):
1907 if not line.startswith( "name=" ):
1908 continue
1909 portVars = {}
1910 for var in line.split( "," ):
1911 key, value = var.split( "=" )
1912 portVars[ key ] = value
1913 isUp = portVars.pop( 'enabled', "True" )
1914 isUp = "True" in isUp
1915 if verbose:
1916 main.log.info( "Reading switch port %s(%s)" %
1917 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
1918 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001919 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001920 mac = None
1921 ips = []
1922 ip = portVars[ 'ip' ]
1923 if ip == 'None':
1924 ip = None
1925 ips.append( ip )
1926 name = portVars[ 'name' ]
1927 if name == 'None':
1928 name = None
1929 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
1930 if name == 'lo':
1931 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
1932 else:
1933 portNo = re.search( portRe, name ).group( 'port' )
1934 ports.append( { 'of_port': portNo,
1935 'mac': str( mac ).replace( '\'', '' ),
1936 'name': name,
1937 'ips': ips,
1938 'enabled': isUp } )
1939 return ports
1940
Jon Halld80cc142015-07-06 13:36:05 -07001941 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001942 """
1943 Read switches from Mininet.
1944
1945 Returns a dictionary whose keys are the switch names and the value is
1946 a dictionary containing information about the switch.
1947 """
Jon Halla22481b2015-07-28 17:46:01 -07001948 # NOTE: To support new Mininet switch classes, just append the new
1949 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07001950
Jon Halla22481b2015-07-28 17:46:01 -07001951 # Regex patterns to parse 'dump' output
1952 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07001953 # <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 -07001954 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07001955 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
1956 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
1957 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
1958 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
1959 swRE = r"<(?P<class>" + switchClasses + r")" +\
1960 r"(?P<options>\{.*\})?\s" +\
1961 r"(?P<name>[^:]+)\:\s" +\
1962 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
1963 r"\spid=(?P<pid>(\d)+)"
Jon Hallafa8a472015-06-12 14:02:42 -07001964 # Update mn port info
1965 self.update()
Jon Halld80cc142015-07-06 13:36:05 -07001966 output = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001967 dump = self.dump().split( "\n" )
1968 for line in dump:
Jon Halla22481b2015-07-28 17:46:01 -07001969 result = re.search( swRE, line, re.I )
1970 if result:
Jon Hallafa8a472015-06-12 14:02:42 -07001971 name = result.group( 'name' )
1972 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
Jon Halla22481b2015-07-28 17:46:01 -07001973 pid = result.group( 'pid' )
1974 swClass = result.group( 'class' )
1975 options = result.group( 'options' )
Jon Hallafa8a472015-06-12 14:02:42 -07001976 if verbose:
1977 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
1978 ports = self.getPorts( name )
Jon Halla22481b2015-07-28 17:46:01 -07001979 output[ name ] = { "dpid": dpid,
1980 "ports": ports,
1981 "swClass": swClass,
1982 "pid": pid,
1983 "options": options }
Jon Hallafa8a472015-06-12 14:02:42 -07001984 return output
1985
Jon Halld80cc142015-07-06 13:36:05 -07001986 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001987 """
1988 Read hosts from Mininet.
1989
1990 Returns a dictionary whose keys are the host names and the value is
1991 a dictionary containing information about the host.
1992 """
1993 # Regex patterns to parse dump output
1994 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07001995 # <Host h1: pid=12725>
1996 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
1997 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
1998 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07001999 # NOTE: Does not correctly match hosts with multi-links
2000 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2001 # FIXME: Fix that
kelvin-onlabd48a68c2015-07-13 16:01:36 -07002002 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Jon Halld80cc142015-07-06 13:36:05 -07002003 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
Jon Hallafa8a472015-06-12 14:02:42 -07002004 # update mn port info
2005 self.update()
2006 # Get mininet dump
2007 dump = self.dump().split( "\n" )
Jon Hall5b0120a2015-06-12 17:35:53 -07002008 hosts = {}
Jon Hallafa8a472015-06-12 14:02:42 -07002009 for line in dump:
kelvin-onlabd48a68c2015-07-13 16:01:36 -07002010 if "Host" in line :
Jon Hallafa8a472015-06-12 14:02:42 -07002011 result = re.search( hostRE, line )
2012 name = result.group( 'name' )
2013 interfaces = []
2014 response = self.getInterfaces( name )
2015 # Populate interface info
2016 for line in response.split( "\n" ):
2017 if line.startswith( "name=" ):
2018 portVars = {}
2019 for var in line.split( "," ):
2020 key, value = var.split( "=" )
2021 portVars[ key ] = value
2022 isUp = portVars.pop( 'enabled', "True" )
2023 isUp = "True" in isUp
2024 if verbose:
2025 main.log.info( "Reading host port %s(%s)" %
2026 ( portVars[ 'name' ],
2027 portVars[ 'mac' ] ) )
2028 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07002029 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07002030 mac = None
2031 ips = []
2032 ip = portVars[ 'ip' ]
2033 if ip == 'None':
2034 ip = None
2035 ips.append( ip )
2036 intfName = portVars[ 'name' ]
2037 if name == 'None':
2038 name = None
2039 interfaces.append( {
2040 "name": intfName,
2041 "ips": ips,
2042 "mac": str( mac ),
2043 "isUp": isUp } )
Jon Hall5b0120a2015-06-12 17:35:53 -07002044 hosts[ name ] = { "interfaces": interfaces }
Jon Hallafa8a472015-06-12 14:02:42 -07002045 return hosts
2046
2047 def getLinks( self ):
2048 """
2049 Gathers information about current Mininet links. These links may not
2050 be up if one of the ports is down.
2051
2052 Returns a list of dictionaries with link endpoints.
2053
2054 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002055 { 'node1': str( node1 name )
2056 'node2': str( node2 name )
2057 'port1': str( port1 of_port )
2058 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002059 Note: The port number returned is the eth#, not necessarily the of_port
2060 number. In Mininet, for OVS switch, these should be the same. For
2061 hosts, this is just the eth#.
2062 """
2063 self.update()
2064 response = self.links().split( '\n' )
2065
2066 # Examples:
2067 # s1-eth3<->s2-eth1 (OK OK)
2068 # s13-eth3<->h27-eth0 (OK OK)
2069 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2070 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2071 links = []
2072 for line in response:
2073 match = re.search( linkRE, line )
2074 if match:
2075 node1 = match.group( 'node1' )
2076 node2 = match.group( 'node2' )
2077 port1 = match.group( 'port1' )
2078 port2 = match.group( 'port2' )
2079 links.append( { 'node1': node1,
2080 'node2': node2,
2081 'port1': port1,
2082 'port2': port2 } )
2083 return links
2084
2085 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002086 """
2087 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002088 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002089
Jon Hallafa8a472015-06-12 14:02:42 -07002090 Dependencies:
2091 1. numpy - "sudo pip install numpy"
2092 """
2093 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002094 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08002095 mnDPIDs = []
Jon Hallafa8a472015-06-12 14:02:42 -07002096 for swName, switch in switches.iteritems():
Jon Hall7eb38402015-01-08 17:19:54 -08002097 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002098 mnDPIDs.sort()
kelvin-onlabd3b64892015-01-20 13:26:24 -08002099 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08002100 main.log.error(
2101 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07002102 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04002103 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08002105 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04002106 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08002107 if switch[ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002108 onosDPIDs.append(
2109 switch[ 'id' ].replace(
2110 ":",
2111 '' ).replace(
2112 "of",
2113 '' ).lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002114 onosDPIDs.sort()
Jon Hall3d87d502014-10-17 18:37:42 -04002115
Jon Hall7eb38402015-01-08 17:19:54 -08002116 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 switchResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002118 main.log.error( "Switches in MN but not in ONOS:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002119 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002120 main.log.error( str( list1 ) )
2121 main.log.error( "Switches in ONOS but not in MN:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002122 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002123 main.log.error( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002124 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08002125 switchResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002126 finalResults = switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04002127
Jon Hall7eb38402015-01-08 17:19:54 -08002128 # FIXME: this does not look for extra ports in ONOS, only checks that
2129 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002130 portsResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002131
Jon Hall7eb38402015-01-08 17:19:54 -08002132 # PORTS
Jon Hallafa8a472015-06-12 14:02:42 -07002133 for name, mnSwitch in switches.iteritems():
kelvin-onlabd3b64892015-01-20 13:26:24 -08002134 mnPorts = []
2135 onosPorts = []
2136 switchResult = main.TRUE
2137 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002138 if port[ 'enabled' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002139 mnPorts.append( int( port[ 'of_port' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 for onosSwitch in portsJson:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002141 if onosSwitch[ 'device' ][ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002142 if onosSwitch[ 'device' ][ 'id' ].replace(
2143 ':',
2144 '' ).replace(
2145 "of",
2146 '' ) == mnSwitch[ 'dpid' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002147 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002148 if port[ 'isEnabled' ]:
2149 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08002150 # onosPorts.append( 'local' )
2151 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002152 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002153 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002154 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 mnPorts.sort( key=float )
2156 onosPorts.sort( key=float )
Jon Hallafa8a472015-06-12 14:02:42 -07002157
kelvin-onlabd3b64892015-01-20 13:26:24 -08002158 mnPortsLog = mnPorts
2159 onosPortsLog = onosPorts
2160 mnPorts = [ x for x in mnPorts ]
2161 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05002162
Jon Hall7eb38402015-01-08 17:19:54 -08002163 # TODO: handle other reserved port numbers besides LOCAL
2164 # NOTE: Reserved ports
2165 # Local port: -2 in Openflow, ONOS shows 'local', we store as
2166 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002167 for mnPort in mnPortsLog:
2168 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08002169 # don't set results to true here as this is just one of
2170 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08002171 mnPorts.remove( mnPort )
2172 onosPorts.remove( mnPort )
Jon Hallafa8a472015-06-12 14:02:42 -07002173
Jon Hall7eb38402015-01-08 17:19:54 -08002174 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05002175 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08002176 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08002177 if 65534 in mnPorts:
2178 mnPorts.remove( 65534 )
2179 if long( uint64( -2 ) ) in onosPorts:
2180 onosPorts.remove( long( uint64( -2 ) ) )
2181 if len( mnPorts ): # the ports of this switch don't match
2182 switchResult = main.FALSE
2183 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
2184 if len( onosPorts ): # the ports of this switch don't match
2185 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002186 main.log.warn(
2187 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08002188 str( onosPorts ) )
2189 if switchResult == main.FALSE:
Jon Hallafa8a472015-06-12 14:02:42 -07002190 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002191 "The list of ports for switch %s(%s) does not match:" %
Jon Hallafa8a472015-06-12 14:02:42 -07002192 ( name, mnSwitch[ 'dpid' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002193 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
2194 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
2195 portsResults = portsResults and switchResult
Jon Hallafa8a472015-06-12 14:02:42 -07002196 finalResults = finalResults and portsResults
2197 return finalResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002198
Jon Hallafa8a472015-06-12 14:02:42 -07002199 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002200 """
2201 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002202 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04002203
Jon Hallafa8a472015-06-12 14:02:42 -07002204 """
Jon Hall7eb38402015-01-08 17:19:54 -08002205 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08002206 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002207 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04002208
Jon Halld80cc142015-07-06 13:36:05 -07002209 mnLinks = []
Jon Hallafa8a472015-06-12 14:02:42 -07002210 for l in links:
2211 try:
2212 node1 = switches[ l[ 'node1' ] ]
2213 node2 = switches[ l[ 'node2' ] ]
2214 enabled = True
2215 for port in node1[ 'ports' ]:
2216 if port[ 'of_port' ] == l[ 'port1' ]:
2217 enabled = enabled and port[ 'enabled' ]
2218 for port in node2[ 'ports' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002219 if port[ 'of_port' ] == l[ 'port2' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002220 enabled = enabled and port[ 'enabled' ]
2221 if enabled:
2222 mnLinks.append( l )
2223 except KeyError:
2224 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002225 if 2 * len( mnLinks ) == len( onos ):
2226 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002227 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002228 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002229 main.log.error(
Jon Hall328ddca2015-01-28 15:57:15 -08002230 "Mininet has " + str( len( mnLinks ) ) +
2231 " bidirectional links and ONOS has " +
2232 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002233
Jon Hall7eb38402015-01-08 17:19:54 -08002234 # iterate through MN links and check if an ONOS link exists in
2235 # both directions
kelvin-onlabd3b64892015-01-20 13:26:24 -08002236 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08002237 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04002238 node1 = None
2239 port1 = None
2240 node2 = None
2241 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08002242 firstDir = main.FALSE
2243 secondDir = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002244 for swName, switch in switches.iteritems():
2245 if swName == link[ 'node1' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002246 node1 = switch[ 'dpid' ]
2247 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002248 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002249 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002250 if node1 is not None and node2 is not None:
2251 break
Jon Hallafa8a472015-06-12 14:02:42 -07002252 if swName == link[ 'node2' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002253 node2 = switch[ 'dpid' ]
2254 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002255 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002256 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002257 if node1 is not None and node2 is not None:
2258 break
2259
kelvin-onlabd3b64892015-01-20 13:26:24 -08002260 for onosLink in onos:
2261 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002262 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002263 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002264 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002265 onosPort1 = onosLink[ 'src' ][ 'port' ]
2266 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002267
Jon Hall72cf1dc2014-10-20 21:04:50 -04002268 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08002269 if str( onosNode1 ) == str( node1 ) and str(
2270 onosNode2 ) == str( node2 ):
2271 if int( onosPort1 ) == int( port1 ) and int(
2272 onosPort2 ) == int( port2 ):
2273 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002274 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002275 main.log.warn(
2276 'The port numbers do not match for ' +
2277 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002278 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002279 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002280 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002281 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002282 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002283
2284 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 elif ( str( onosNode1 ) == str( node2 ) and
2286 str( onosNode2 ) == str( node1 ) ):
2287 if ( int( onosPort1 ) == int( port2 )
2288 and int( onosPort2 ) == int( port1 ) ):
2289 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002290 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002291 main.log.warn(
2292 'The port numbers do not match for ' +
2293 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002294 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002295 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002296 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002297 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002298 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002299 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04002300 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002301 if not firstDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002302 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002303 'ONOS does not have the link %s/%s -> %s/%s' %
2304 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002305 if not secondDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002306 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002307 'ONOS does not have the link %s/%s -> %s/%s' %
2308 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002309 linkResults = linkResults and firstDir and secondDir
2310 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002311
Jon Hallafa8a472015-06-12 14:02:42 -07002312 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08002313 """
Jon Hallafa8a472015-06-12 14:02:42 -07002314 Compare mn and onos Hosts.
2315 Since Mininet hosts are quiet, ONOS will only know of them when they
2316 speak. For this reason, we will only check that the hosts in ONOS
2317 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08002318
Jon Hallafa8a472015-06-12 14:02:42 -07002319 Arguments:
2320 hostsJson: parsed json object from the onos hosts api
2321 Returns:
2322 """
Jon Hallff6b4b22015-02-23 09:25:15 -08002323 import json
2324 hostResults = main.TRUE
Jon Hallff6b4b22015-02-23 09:25:15 -08002325 for onosHost in hostsJson:
2326 onosMAC = onosHost[ 'mac' ].lower()
2327 match = False
Jon Halld80cc142015-07-06 13:36:05 -07002328 for mnHost, info in hosts.iteritems():
2329 for mnIntf in info[ 'interfaces' ]:
2330 if onosMAC == mnIntf[ 'mac' ].lower():
Jon Hallff6b4b22015-02-23 09:25:15 -08002331 match = True
2332 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002333 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002334 pass # all is well
2335 else:
2336 # misssing ip
Jon Halld80cc142015-07-06 13:36:05 -07002337 main.log.error( "ONOS host " +
2338 onosHost[ 'id' ] +
2339 " has a different IP(" +
Jon Hallafa8a472015-06-12 14:02:42 -07002340 str( onosHost[ 'ipAddresses' ] ) +
2341 ") than the Mininet host(" +
Jon Halld80cc142015-07-06 13:36:05 -07002342 str( ip ) +
2343 ")." )
Jon Hallff6b4b22015-02-23 09:25:15 -08002344 output = json.dumps(
Jon Halld80cc142015-07-06 13:36:05 -07002345 onosHost,
2346 sort_keys=True,
2347 indent=4,
2348 separators=( ',', ': ' ) )
Jon Hallff6b4b22015-02-23 09:25:15 -08002349 main.log.info( output )
2350 hostResults = main.FALSE
2351 if not match:
2352 hostResults = main.FALSE
2353 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2354 "corresponding Mininet host." )
2355 output = json.dumps( onosHost,
2356 sort_keys=True,
2357 indent=4,
2358 separators=( ',', ': ' ) )
2359 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002360 return hostResults
2361
Jon Hallafa8a472015-06-12 14:02:42 -07002362 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002363 """
2364 Returns a list of all hosts
2365 Don't ask questions just use it"""
2366 self.handle.sendline( "" )
2367 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002368
Jon Hall7eb38402015-01-08 17:19:54 -08002369 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2370 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002371
kelvin-onlabd3b64892015-01-20 13:26:24 -08002372 handlePy = self.handle.before
2373 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2374 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002375
Jon Hall7eb38402015-01-08 17:19:54 -08002376 self.handle.sendline( "" )
2377 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002378
kelvin-onlabd3b64892015-01-20 13:26:24 -08002379 hostStr = handlePy.replace( "]", "" )
2380 hostStr = hostStr.replace( "'", "" )
2381 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002382 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002383 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002384
kelvin-onlabd3b64892015-01-20 13:26:24 -08002385 return hostList
adminbae64d82013-08-01 10:50:15 -07002386
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002387 def getSwitch( self ):
2388 """
2389 Returns a list of all switches
2390 Again, don't ask question just use it...
2391 """
2392 # get host list...
2393 hostList = self.getHosts()
2394 # Make host set
2395 hostSet = set( hostList )
2396
2397 # Getting all the nodes in mininet
2398 self.handle.sendline( "" )
2399 self.handle.expect( "mininet>" )
2400
2401 self.handle.sendline( "py [ node.name for node in net.values() ]" )
2402 self.handle.expect( "mininet>" )
2403
2404 handlePy = self.handle.before
2405 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2406 handlePy = handlePy.rstrip()
2407
2408 self.handle.sendline( "" )
2409 self.handle.expect( "mininet>" )
2410
2411 nodesStr = handlePy.replace( "]", "" )
2412 nodesStr = nodesStr.replace( "'", "" )
2413 nodesStr = nodesStr.replace( "[", "" )
2414 nodesStr = nodesStr.replace( " ", "" )
2415 nodesList = nodesStr.split( "," )
2416
2417 nodesSet = set( nodesList )
2418 # discarding default controller(s) node
2419 nodesSet.discard( 'c0' )
2420 nodesSet.discard( 'c1' )
2421 nodesSet.discard( 'c2' )
2422
2423 switchSet = nodesSet - hostSet
2424 switchList = list( switchSet )
2425
2426 return switchList
2427
Jon Hall7eb38402015-01-08 17:19:54 -08002428 def update( self ):
2429 """
2430 updates the port address and status information for
2431 each port in mn"""
2432 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002433 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002434 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002435 self.handle.sendline( "" )
2436 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002437
Jon Hall7eb38402015-01-08 17:19:54 -08002438 self.handle.sendline( "update" )
2439 self.handle.expect( "update" )
2440 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002441
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 Hallb1290e82014-11-18 16:17:48 -05002445 return main.TRUE
2446 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002447 main.log.error( self.name + ": EOF exception found" )
2448 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002449 main.cleanup()
2450 main.exit()
2451
Jon Halld80cc142015-07-06 13:36:05 -07002452 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07002453 """
2454 Add vlan tag to a host.
2455 Dependencies:
2456 This class depends on the "vlan" package
2457 $ sudo apt-get install vlan
2458 Configuration:
2459 Load the 8021q module into the kernel
2460 $sudo modprobe 8021q
2461
2462 To make this setup permanent:
2463 $ sudo su -c 'echo "8021q" >> /etc/modules'
2464 """
2465 if self.handle:
2466 try:
Jon Halld80cc142015-07-06 13:36:05 -07002467 # get the ip address of the host
2468 main.log.info( "Get the ip address of the host" )
2469 ipaddr = self.getIPAddress( host )
2470 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07002471
Jon Halld80cc142015-07-06 13:36:05 -07002472 # remove IP from interface intf
2473 # Ex: h1 ifconfig h1-eth0 inet 0
2474 main.log.info( "Remove IP from interface " )
2475 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2476 self.handle.sendline( cmd2 )
2477 self.handle.expect( "mininet>" )
2478 response = self.handle.before
2479 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002480
Jon Halld80cc142015-07-06 13:36:05 -07002481 # create VLAN interface
2482 # Ex: h1 vconfig add h1-eth0 100
2483 main.log.info( "Create Vlan" )
2484 cmd3 = host + " vconfig add " + intf + " " + vlan
2485 self.handle.sendline( cmd3 )
2486 self.handle.expect( "mininet>" )
2487 response = self.handle.before
2488 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002489
Jon Halld80cc142015-07-06 13:36:05 -07002490 # assign the host's IP to the VLAN interface
2491 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2492 main.log.info( "Assign the host IP to the vlan interface" )
2493 vintf = intf + "." + vlan
2494 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2495 self.handle.sendline( cmd4 )
2496 self.handle.expect( "mininet>" )
2497 response = self.handle.before
2498 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002499
2500 return main.TRUE
2501 except pexpect.EOF:
2502 main.log.error( self.name + ": EOF exception found" )
2503 main.log.error( self.name + ": " + self.handle.before )
2504 return main.FALSE
2505
adminbae64d82013-08-01 10:50:15 -07002506if __name__ != "__main__":
2507 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002508 sys.modules[ __name__ ] = MininetCliDriver()