blob: ef4c812247fad17bacda5413ded8421a76ea7f27 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
Jon Hallbe6dfc42015-01-12 17:37:25 -080021MininetCliDriver is the basic driver which will handle the Mininet functions
22
23Some functions rely on a modified version of Mininet. These functions
24should all be noted in the comments. To get this MN version run these commands
25from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080026 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080027 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080028 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git pull
30
Jon Hall272a4db2015-01-12 17:43:48 -080031
32 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080033changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070034import pexpect
adminbae64d82013-08-01 10:50:15 -070035import re
36import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070037import types
kelvin-onlaba4074292015-07-09 15:19:49 -070038import os
Jon Hall1ccf82c2014-10-15 14:55:16 -040039from math import pow
adminbae64d82013-08-01 10:50:15 -070040from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070041
Jon Hall7eb38402015-01-08 17:19:54 -080042
kelvin-onlab50907142015-04-01 13:37:45 -070043class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080044
45 """
46 MininetCliDriver is the basic driver which will handle
47 the Mininet functions"""
48 def __init__( self ):
49 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070050 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080051 self.name = None
kelvin-onlabd9e23de2015-08-06 10:34:44 -070052 self.home = None
Jon Hall7eb38402015-01-08 17:19:54 -080053 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070054 self.flag = 0
55
Jon Hall7eb38402015-01-08 17:19:54 -080056 def connect( self, **connectargs ):
57 """
58 Here the main is the TestON instance after creating
59 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080060 try:
61 for key in connectargs:
62 vars( self )[ key ] = connectargs[ key ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070063 self.home = "~/mininet"
kelvin-onlaba1484582015-02-02 15:46:20 -080064 self.name = self.options[ 'name' ]
kelvin-onlabd9e23de2015-08-06 10:34:44 -070065 for key in self.options:
66 if key == "home":
67 self.home = self.options[ 'home' ]
68 break
69 if self.home is None or self.home == "":
70 self.home = "~/mininet"
kelvin-onlaba4074292015-07-09 15:19:49 -070071
72 try:
73 if os.getenv( str( self.ip_address ) ) != None:
74 self.ip_address = os.getenv( str( self.ip_address ) )
75 else:
76 main.log.info( self.name +
77 ": Trying to connect to " +
78 self.ip_address )
79
80 except KeyError:
81 main.log.info( "Invalid host name," +
82 " connecting to local host instead" )
83 self.ip_address = 'localhost'
84 except Exception as inst:
85 main.log.error( "Uncaught exception: " + str( inst ) )
86
kelvin-onlaba1484582015-02-02 15:46:20 -080087 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070088 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080089 self ).connect(
90 user_name=self.user_name,
91 ip_address=self.ip_address,
92 port=None,
93 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080094
kelvin-onlaba1484582015-02-02 15:46:20 -080095 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080096 main.log.info( "Connection successful to the host " +
97 self.user_name +
98 "@" +
99 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -0800100 return main.TRUE
101 else:
102 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -0800103 self.user_name +
104 "@" +
105 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -0800106 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800107 return main.FALSE
108 except pexpect.EOF:
109 main.log.error( self.name + ": EOF exception found" )
110 main.log.error( self.name + ": " + self.handle.before )
111 main.cleanup()
112 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800113 except Exception:
114 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800115 main.cleanup()
116 main.exit()
117
kelvin-onlab10e8d392015-06-03 13:53:45 -0700118 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800119 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700120 Description:
121 Starts Mininet accepts a topology(.py) file and/or an optional
122 argument, to start the mininet, as a parameter.
123 Can also send regular mininet command to load up desired topology.
124 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
125 Options:
126 topoFile = file path for topology file (.py)
127 args = extra option added when starting the topology from the file
128 mnCmd = Mininet command use to start topology
129 Returns:
130 main.TRUE if the mininet starts successfully, main.FALSE
131 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800132 """
Jon Hall7eb38402015-01-08 17:19:54 -0800133 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700134 # make sure old networks are cleaned up
135 main.log.info( self.name +
136 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800137 self.handle.sendline( "sudo mn -c" )
138 i = self.handle.expect( [ 'password\sfor\s',
139 'Cleanup\scomplete',
140 pexpect.EOF,
141 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800142 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800143 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700144 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800145 main.log.info( self.name + ": Sending sudo password" )
146 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800147 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800148 '\$',
149 pexpect.EOF,
150 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800151 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800152 if i == 1:
153 main.log.info( self.name + ": Clean" )
154 elif i == 2:
155 main.log.error( self.name + ": Connection terminated" )
156 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700157 main.log.error( self.name + ": Something while cleaning " +
158 "Mininet took too long... " )
159 # Craft the string to start mininet
160 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700161 if not mnCmd:
162 if topoFile is None or topoFile == '': # If no file is given
163 main.log.info( self.name + ": building fresh Mininet" )
164 cmdString += "mn "
165 if args is None or args == '':
166 # If no args given, use args from .topo file
167 args = self.options[ 'arg1' ] +\
Jon Halld80cc142015-07-06 13:36:05 -0700168 " " + self.options[ 'arg2' ] +\
169 " --mac --controller " +\
170 self.options[ 'controller' ] + " " +\
171 self.options[ 'arg3' ]
kelvin-onlab10e8d392015-06-03 13:53:45 -0700172 else: # else only use given args
173 pass
174 # TODO: allow use of topo args and method args?
175 else: # Use given topology file
Jon Halld80cc142015-07-06 13:36:05 -0700176 main.log.info(
177 "Starting Mininet from topo file " +
178 topoFile )
kelvin-onlab10e8d392015-06-03 13:53:45 -0700179 cmdString += topoFile + " "
180 if args is None:
181 args = ''
182 # TODO: allow use of args from .topo file?
183 cmdString += args
184 else:
185 main.log.info( "Starting Mininet topology using '" + mnCmd +
186 "' command" )
187 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700188 # Send the command and check if network started
189 self.handle.sendline( "" )
190 self.handle.expect( '\$' )
191 main.log.info( "Sending '" + cmdString + "' to " + self.name )
192 self.handle.sendline( cmdString )
193 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800194 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700195 'Exception',
196 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800197 pexpect.EOF,
198 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700199 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800200 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700201 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800202 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800203 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700204 response = str( self.handle.before +
205 self.handle.after )
206 self.handle.expect( '\$' )
207 response += str( self.handle.before +
Jon Halld80cc142015-07-06 13:36:05 -0700208 self.handle.after )
Jon Hall689d8e42015-04-03 13:59:24 -0700209 main.log.error(
210 self.name +
211 ": Launching Mininet failed: " + response )
212 return main.FALSE
213 elif i == 2:
214 self.handle.expect( [ "\n",
215 pexpect.EOF,
216 pexpect.TIMEOUT ],
217 timeout )
218 main.log.info( self.handle.before )
219 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800220 main.log.error( self.name + ": Connection timeout" )
221 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700222 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800223 main.log.error(
224 self.name +
225 ": Something took too long... " )
226 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700227 # Why did we hit this part?
228 main.log.error( "startNet did not return correctly" )
229 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800230 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700231 main.log.error( self.name + ": Connection failed to the host " +
232 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800233 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700234 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800235
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800236 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400237 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800238 # In tree topology, if fanout arg is not given, by default it is 2
239 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400240 fanout = 2
241 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500242 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800243 while( k <= depth - 1 ):
244 count = count + pow( fanout, k )
245 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800247 while( k <= depth - 2 ):
248 # depth-2 gives you only core links and not considering
249 # edge links as seen by ONOS. If all the links including
250 # edge links are required, do depth-1
251 count = count + pow( fanout, k )
252 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800254 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800256
Jon Hall7eb38402015-01-08 17:19:54 -0800257 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800259 # by default it is 1
260 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400261 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 numSwitches = depth
263 numHostsPerSw = fanout
264 totalNumHosts = numSwitches * numHostsPerSw
265 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800266 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800268 topoDict = { "num_switches": int( numSwitches ),
269 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400270 return topoDict
271
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700273 """
274 Calculate the number of switches and links in a topo."""
275 # TODO: combine this function and numSwitchesNlinks
276 argList = self.options[ 'arg1' ].split( "," )
277 topoArgList = argList[ 0 ].split( " " )
278 argList = map( int, argList[ 1: ] )
279 topoArgList = topoArgList[ 1: ] + argList
280
281 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400282 return topoDict
283
Jon Halld80cc142015-07-06 13:36:05 -0700284 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800285 """
286 Verifies the reachability of the hosts using pingall command.
287 Optional parameter timeout allows you to specify how long to
288 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700289 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700290 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700291 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700292 ping
293 acceptableFailed - Set the number of acceptable failed pings for the
294 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800295 Returns:
296 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700297 otherwise main.FALSE
298 """
299 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700300 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700301 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700302 if self.handle:
303 main.log.info(
304 self.name +
305 ": Checking reachabilty to the hosts using pingall" )
306 response = ""
307 failedPings = 0
308 returnValue = main.TRUE
309 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700310 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700311 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700312 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700313 pexpect.EOF,
314 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700315 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700316 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700317 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700318 response += self.handle.before
319 break
320 elif i == 1:
321 response += self.handle.before + self.handle.after
322 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700323 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700324 returnValue = main.FALSE
325 if shortCircuit:
326 main.log.error( self.name +
327 ": Aborting pingall - "
328 + str( failedPings ) +
329 " pings failed" )
330 break
Jon Hall390696c2015-05-05 17:13:41 -0700331 if ( time.time() - startTime ) > timeout:
332 returnValue = main.FALSE
333 main.log.error( self.name +
334 ": Aborting pingall - " +
335 "Function took too long " )
336 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700337 elif i == 2:
338 main.log.error( self.name +
339 ": EOF exception found" )
340 main.log.error( self.name + ": " +
341 self.handle.before )
342 main.cleanup()
343 main.exit()
344 elif i == 3:
345 response += self.handle.before
346 main.log.error( self.name +
347 ": TIMEOUT exception found" )
348 main.log.error( self.name +
349 ": " +
350 str( response ) )
351 # NOTE: Send ctrl-c to make sure pingall is done
352 self.handle.sendline( "\x03" )
353 self.handle.expect( "Interrupt" )
354 self.handle.expect( "mininet>" )
355 break
356 pattern = "Results\:"
357 main.log.info( "Pingall output: " + str( response ) )
358 if re.search( pattern, response ):
359 main.log.info( self.name + ": Pingall finished with "
360 + str( failedPings ) + " failed pings" )
361 return returnValue
362 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700363 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700364 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700365 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700366 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700367 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700368 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700369 main.log.error( self.name + ": Connection failed to the host" )
370 main.cleanup()
371 main.exit()
372 except pexpect.TIMEOUT:
373 if response:
374 main.log.info( "Pingall output: " + str( response ) )
375 main.log.error( self.name + ": pexpect.TIMEOUT found" )
376 return main.FALSE
377 except pexpect.EOF:
378 main.log.error( self.name + ": EOF exception found" )
379 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500380 main.cleanup()
381 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700382
Jon Hall7eb38402015-01-08 17:19:54 -0800383 def fpingHost( self, **pingParams ):
384 """
385 Uses the fping package for faster pinging...
386 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800387 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800388 command = args[ "SRC" ] + \
389 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
390 self.handle.sendline( command )
391 self.handle.expect(
392 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
393 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
394 response = self.handle.before
395 if re.search( ":\s-", response ):
396 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700397 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800398 elif re.search( ":\s\d{1,2}\.\d\d", response ):
399 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700400 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800401 main.log.info( self.name + ": Install fping on mininet machine... " )
402 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700403 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800404
Hari Krishna9592fc82015-07-31 15:11:15 -0700405 def pingallHosts( self, hostList ):
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 """
Hari Krishna9592fc82015-07-31 15:11:15 -0700407 Ping all specified IPv4 hosts
kelvin-onlab2ff57022015-05-29 10:48:51 -0700408
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400409 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700410 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700411
412 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400413 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700414
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400415 Returns main.FALSE if one or more of hosts specified
416 cannot reach each other"""
Hari Krishna9592fc82015-07-31 15:11:15 -0700417
418 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400419
420 try:
421 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700422
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400423 isReachable = main.TRUE
424
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400425 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700426 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400427 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700428 pingList = hostList[ :listIndex ] + \
429 hostList[ ( listIndex + 1 ): ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700430
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400431 for temp in pingList:
432 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700433 pingCmd = str( host ) + cmd + str( temp )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400434 self.handle.sendline( pingCmd )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700435 self.handle.expect( "mininet>" )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400436 response = self.handle.before
437 if re.search( ',\s0\%\spacket\sloss', response ):
Jon Halld80cc142015-07-06 13:36:05 -0700438 main.log.info( str( host ) + " -> " + str( temp ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400439 else:
Jon Halld80cc142015-07-06 13:36:05 -0700440 main.log.info(
441 str( host ) + " -> X (" + str( temp ) + ") "
442 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400443 # One of the host to host pair is unreachable
444 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400445
kelvin-onlab2ff57022015-05-29 10:48:51 -0700446 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400447
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700448 except pexpect.TIMEOUT:
449 main.log.exception( self.name + ": TIMEOUT exception" )
Hari Krishna4223dbd2015-08-13 16:29:53 -0700450 return main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400451 except pexpect.EOF:
452 main.log.error( self.name + ": EOF exception found" )
453 main.log.error( self.name + ": " + self.handle.before )
454 main.cleanup()
455 main.exit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700456 except Exception:
457 main.log.exception( self.name + ": Uncaught exception!" )
458 main.cleanup()
459 main.exit()
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400460
kelvin-onlab9b42b0a2015-08-05 14:43:58 -0700461 def pingIpv6Hosts(self, hostList, prefix='1000::'):
Hari Krishna9592fc82015-07-31 15:11:15 -0700462 """
463 IPv6 ping all hosts in hostList. If no prefix passed this will use
464 default prefix of 1000::
465
466 Returns main.TRUE if all hosts specified can reach each other
467
468 Returns main.FALSE if one or more of hosts specified cannot reach each other
469 """
470 try:
471 main.log.info( "Testing reachability between specified IPv6 hosts" )
472 isReachable = main.TRUE
473 cmd = " ping6 -c 1 -i 1 -W 8 "
474 for host in hostList:
475 listIndex = hostList.index( host )
476 # List of hosts to ping other than itself
477 pingList = hostList[ :listIndex ] + \
478 hostList[ ( listIndex + 1 ): ]
479
480 for temp in pingList:
481 # Current host pings all other hosts specified
482 pingCmd = str( host ) + cmd + prefix + str( temp[1:] )
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700483 self.handle.sendline( pingCmd )
484 self.handle.expect( "mininet>" )
Hari Krishna9592fc82015-07-31 15:11:15 -0700485 response = self.handle.before
486 if re.search( ',\s0\%\spacket\sloss', response ):
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700487 main.log.info( str( host ) + " -> " + prefix + str( temp[1:] ) )
Hari Krishna9592fc82015-07-31 15:11:15 -0700488 else:
489 main.log.info(
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700490 str( host ) + " -> X (" + prefix + str( temp[1:] ) + ") "
Hari Krishna9592fc82015-07-31 15:11:15 -0700491 " Destination Unreachable" )
492 main.log.error( "Response from Mininet: " + str( response ) )
493 # One of the host to host pair is unreachable
494 isReachable = main.FALSE
495 return isReachable
496
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700497 except pexpect.TIMEOUT:
498 main.log.exception( self.name + ": TIMEOUT exception" )
499 return main.FALSE
Hari Krishna9592fc82015-07-31 15:11:15 -0700500 except pexpect.EOF:
501 main.log.error( self.name + ": EOF exception found" )
502 main.log.error( self.name + ": " + self.handle.before )
503 main.cleanup()
504 main.exit()
Hari Krishna3bf8ea82015-08-11 09:02:02 -0700505 except Exception:
506 main.log.exception( self.name + ": Uncaught exception!" )
507 main.cleanup()
508 main.exit()
Hari Krishna9592fc82015-07-31 15:11:15 -0700509
Jon Hall7eb38402015-01-08 17:19:54 -0800510 def pingHost( self, **pingParams ):
511 """
512 Ping from one mininet host to another
513 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800514 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800515 command = args[ "SRC" ] + " ping " + \
516 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700517 try:
Jon Hall61282e32015-03-19 11:34:11 -0700518 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800519 self.handle.sendline( command )
520 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700521 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800522 main.log.error(
523 self.name +
524 ": timeout when waiting for response from mininet" )
525 main.log.error( "response: " + str( self.handle.before ) )
526 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700527 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800528 main.log.error(
529 self.name +
530 ": timeout when waiting for response from mininet" )
531 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700532 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800533 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800534 main.log.error( self.name + ": EOF exception found" )
535 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700536 main.cleanup()
537 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800538 main.log.info( self.name + ": Ping Response: " + response )
539 if re.search( ',\s0\%\spacket\sloss', response ):
540 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700542 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800543 else:
544 main.log.error(
545 self.name +
546 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700548 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800549
Jon Hall7eb38402015-01-08 17:19:54 -0800550 def checkIP( self, host ):
551 """
552 Verifies the host's ip configured or not."""
553 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700554 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800555 response = self.execute(
556 cmd=host +
557 " ifconfig",
558 prompt="mininet>",
559 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800560 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800561 main.log.error( self.name + ": EOF exception found" )
562 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700563 main.cleanup()
564 main.exit()
adminbae64d82013-08-01 10:50:15 -0700565
Jon Hall7eb38402015-01-08 17:19:54 -0800566 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800567 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
568 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
569 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
570 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
571 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800572 # pattern = "inet addr:10.0.0.6"
573 if re.search( pattern, response ):
574 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700575 return main.TRUE
576 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800577 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700578 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800579 else:
580 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800581
Jon Hall7eb38402015-01-08 17:19:54 -0800582 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800583 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700584 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800585 response = self.execute(
586 cmd="h1 /usr/sbin/sshd -D&",
587 prompt="mininet>",
588 timeout=10 )
589 response = self.execute(
590 cmd="h4 /usr/sbin/sshd -D&",
591 prompt="mininet>",
592 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700593 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800594 vars( self )[ key ] = connectargs[ key ]
595 response = self.execute(
596 cmd="xterm h1 h4 ",
597 prompt="mininet>",
598 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800599 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800600 main.log.error( self.name + ": EOF exception found" )
601 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700602 main.cleanup()
603 main.exit()
adminbae64d82013-08-01 10:50:15 -0700604 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800605 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700606 if self.flag == 0:
607 self.flag = 1
608 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800609 else:
adminbae64d82013-08-01 10:50:15 -0700610 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800611
kelvin-onlaba1484582015-02-02 15:46:20 -0800612 def moveHost( self, host, oldSw, newSw, ):
613 """
614 Moves a host from one switch to another on the fly
615 Note: The intf between host and oldSw when detached
616 using detach(), will still show up in the 'net'
617 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700618 ( which is correct behavior since the interfaces
619 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800620 """
621 if self.handle:
622 try:
623 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700624 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800625 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800626 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800627 response = self.execute( cmd=cmd,
628 prompt="mininet>",
629 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700630
kelvin-onlaba1484582015-02-02 15:46:20 -0800631 # Determine hostintf and Oldswitchintf
632 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800633 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800634 print "cmd2= ", cmd
635 self.handle.sendline( cmd )
636 self.handle.expect( "mininet>" )
637
shahshreya73537862015-02-11 15:15:24 -0800638 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800639 cmd = "px ipaddr = hintf.IP()"
640 print "cmd3= ", cmd
641 self.handle.sendline( cmd )
642 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800643
644 cmd = "px macaddr = hintf.MAC()"
645 print "cmd3= ", cmd
646 self.handle.sendline( cmd )
647 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700648
kelvin-onlaba1484582015-02-02 15:46:20 -0800649 # Detach interface between oldSw-host
650 cmd = "px " + oldSw + ".detach( sintf )"
651 print "cmd4= ", cmd
652 self.handle.sendline( cmd )
653 self.handle.expect( "mininet>" )
654
655 # Add link between host-newSw
656 cmd = "py net.addLink(" + host + "," + newSw + ")"
657 print "cmd5= ", cmd
658 self.handle.sendline( cmd )
659 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700660
kelvin-onlaba1484582015-02-02 15:46:20 -0800661 # Determine hostintf and Newswitchintf
662 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800663 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800664 print "cmd6= ", cmd
665 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700666 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800667
668 # Attach interface between newSw-host
669 cmd = "px " + newSw + ".attach( sintf )"
670 print "cmd3= ", cmd
671 self.handle.sendline( cmd )
672 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700673
kelvin-onlaba1484582015-02-02 15:46:20 -0800674 # Set ipaddress of the host-newSw interface
675 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
676 print "cmd7 = ", cmd
677 self.handle.sendline( cmd )
678 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800679
680 # Set macaddress of the host-newSw interface
681 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
682 print "cmd8 = ", cmd
683 self.handle.sendline( cmd )
684 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700685
kelvin-onlaba1484582015-02-02 15:46:20 -0800686 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800687 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800688 self.handle.sendline( cmd )
689 self.handle.expect( "mininet>" )
690 print "output = ", self.handle.before
691
692 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800693 cmd = host + " ifconfig"
694 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800695 self.handle.sendline( cmd )
696 self.handle.expect( "mininet>" )
697 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700698
kelvin-onlaba1484582015-02-02 15:46:20 -0800699 return main.TRUE
700 except pexpect.EOF:
701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
703 return main.FALSE
704
Jon Hall7eb38402015-01-08 17:19:54 -0800705 def changeIP( self, host, intf, newIP, newNetmask ):
706 """
707 Changes the ip address of a host on the fly
708 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800709 if self.handle:
710 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800711 cmd = host + " ifconfig " + intf + " " + \
712 newIP + " " + 'netmask' + " " + newNetmask
713 self.handle.sendline( cmd )
714 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800715 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800716 main.log.info( "response = " + response )
717 main.log.info(
718 "Ip of host " +
719 host +
720 " changed to new IP " +
721 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800722 return main.TRUE
723 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800724 main.log.error( self.name + ": EOF exception found" )
725 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800726 return main.FALSE
727
Jon Hall7eb38402015-01-08 17:19:54 -0800728 def changeDefaultGateway( self, host, newGW ):
729 """
730 Changes the default gateway of a host
731 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800732 if self.handle:
733 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800734 cmd = host + " route add default gw " + newGW
735 self.handle.sendline( cmd )
736 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800737 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800738 main.log.info( "response = " + response )
739 main.log.info(
740 "Default gateway of host " +
741 host +
742 " changed to " +
743 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800744 return main.TRUE
745 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800746 main.log.error( self.name + ": EOF exception found" )
747 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800748 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800749
Jon Hall7eb38402015-01-08 17:19:54 -0800750 def addStaticMACAddress( self, host, GW, macaddr ):
751 """
Jon Hallefbd9792015-03-05 16:11:36 -0800752 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800753 if self.handle:
754 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800755 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
756 cmd = host + " arp -s " + GW + " " + macaddr
757 self.handle.sendline( cmd )
758 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800759 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800760 main.log.info( "response = " + response )
761 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800762 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800763 GW +
764 " changed to " +
765 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800766 return main.TRUE
767 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800768 main.log.error( self.name + ": EOF exception found" )
769 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800770 return main.FALSE
771
Jon Hall7eb38402015-01-08 17:19:54 -0800772 def verifyStaticGWandMAC( self, host ):
773 """
774 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800775 if self.handle:
776 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800777 # h1 arp -an
778 cmd = host + " arp -an "
779 self.handle.sendline( cmd )
780 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800781 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800782 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800783 return main.TRUE
784 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800785 main.log.error( self.name + ": EOF exception found" )
786 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800787 return main.FALSE
788
Jon Hall7eb38402015-01-08 17:19:54 -0800789 def getMacAddress( self, host ):
790 """
791 Verifies the host's ip configured or not."""
792 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700793 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800794 response = self.execute(
795 cmd=host +
796 " ifconfig",
797 prompt="mininet>",
798 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800799 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800800 main.log.error( self.name + ": EOF exception found" )
801 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700802 main.cleanup()
803 main.exit()
adminbae64d82013-08-01 10:50:15 -0700804
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700805 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800806 macAddressSearch = re.search( pattern, response, re.I )
807 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800808 main.log.info(
809 self.name +
810 ": Mac-Address of Host " +
811 host +
812 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800813 macAddress )
814 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700815 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800816 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700817
Jon Hall7eb38402015-01-08 17:19:54 -0800818 def getInterfaceMACAddress( self, host, interface ):
819 """
820 Return the IP address of the interface on the given host"""
821 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700822 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800823 response = self.execute( cmd=host + " ifconfig " + interface,
824 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800825 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800826 main.log.error( self.name + ": EOF exception found" )
827 main.log.error( self.name + ": " + self.handle.before )
828 main.cleanup()
829 main.exit()
830
831 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800832 macAddressSearch = re.search( pattern, response, re.I )
833 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800834 main.log.info( "No mac address found in %s" % response )
835 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800836 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800837 main.log.info(
838 "Mac-Address of " +
839 host +
840 ":" +
841 interface +
842 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800843 macAddress )
844 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800845 else:
846 main.log.error( "Connection failed to the host" )
847
848 def getIPAddress( self, host ):
849 """
850 Verifies the host's ip configured or not."""
851 if self.handle:
852 try:
853 response = self.execute(
854 cmd=host +
855 " ifconfig",
856 prompt="mininet>",
857 timeout=10 )
858 except pexpect.EOF:
859 main.log.error( self.name + ": EOF exception found" )
860 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700861 main.cleanup()
862 main.exit()
adminbae64d82013-08-01 10:50:15 -0700863
864 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800866 main.log.info(
867 self.name +
868 ": IP-Address of Host " +
869 host +
870 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 ipAddressSearch.group( 1 ) )
872 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800873 else:
874 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800875
Jon Hall7eb38402015-01-08 17:19:54 -0800876 def getSwitchDPID( self, switch ):
877 """
878 return the datapath ID of the switch"""
879 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700880 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700881 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800882 response = self.execute(
883 cmd=cmd,
884 prompt="mininet>",
885 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800886 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( self.name + ": EOF exception found" )
888 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700889 main.cleanup()
890 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800891 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800892 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700893 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800894 main.log.info(
895 "Couldn't find DPID for switch %s, found: %s" %
896 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700897 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800898 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700899 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800900 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700901
Jon Hall7eb38402015-01-08 17:19:54 -0800902 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700903 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800904 self.handle.sendline( "" )
905 self.expect( "mininet>" )
906 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700907 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800908 response = self.execute(
909 cmd=cmd,
910 prompt="mininet>",
911 timeout=10 )
912 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700913 response = self.handle.before
914 return response
915 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800916 main.log.error( self.name + ": EOF exception found" )
917 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700918 main.cleanup()
919 main.exit()
920
Jon Hall7eb38402015-01-08 17:19:54 -0800921 def getInterfaces( self, node ):
922 """
923 return information dict about interfaces connected to the node"""
924 if self.handle:
925 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800926 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700927 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700928 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800929 response = self.execute(
930 cmd=cmd,
931 prompt="mininet>",
932 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800933 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800934 main.log.error( self.name + ": EOF exception found" )
935 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700936 main.cleanup()
937 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700938 return response
939 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800940 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700941
Jon Hall7eb38402015-01-08 17:19:54 -0800942 def dump( self ):
943 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700944 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800945 response = self.execute(
946 cmd='dump',
947 prompt='mininet>',
948 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800949 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700952 main.cleanup()
953 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700954 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800955
Jon Hall7eb38402015-01-08 17:19:54 -0800956 def intfs( self ):
957 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700958 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800959 response = self.execute(
960 cmd='intfs',
961 prompt='mininet>',
962 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800963 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800964 main.log.error( self.name + ": EOF exception found" )
965 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700966 main.cleanup()
967 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700968 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800969
Jon Hall7eb38402015-01-08 17:19:54 -0800970 def net( self ):
971 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700972 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800973 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800974 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800975 main.log.error( self.name + ": EOF exception found" )
976 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700977 main.cleanup()
978 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700979 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800980
Jon Hallafa8a472015-06-12 14:02:42 -0700981 def links( self ):
982 main.log.info( self.name + ": List network links" )
983 try:
984 response = self.execute( cmd='links', prompt='mininet>',
985 timeout=10 )
986 except pexpect.EOF:
987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
989 main.cleanup()
990 main.exit()
991 return response
992
GlennRC61321f22015-07-16 13:36:54 -0700993 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700994 '''
995 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -0700996
kelvin-onlab7cce9382015-07-17 10:21:03 -0700997 @parm:
998 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
999 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1000 '''
1001 for host1 in hosts:
1002 for host2 in hosts:
1003 if host1 != host2:
1004 if self.iperftcp(host1, host2, timeout) == main.FALSE:
1005 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
GlennRC61321f22015-07-16 13:36:54 -07001006
1007 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -07001008 '''
1009 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
1010 are valid.
GlennRC61321f22015-07-16 13:36:54 -07001011
kelvin-onlab7cce9382015-07-17 10:21:03 -07001012 @parm:
1013 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
1014 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
1015 '''
1016 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
1017 try:
1018 # Setup the mininet command
1019 cmd1 = 'iperf ' + host1 + " " + host2
1020 self.handle.sendline( cmd1 )
1021 outcome = self.handle.expect( "mininet>", timeout )
1022 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001023
kelvin-onlab7cce9382015-07-17 10:21:03 -07001024 # checks if there are results in the mininet response
1025 if "Results:" in response:
1026 main.log.report(self.name + ": iperf test completed")
1027 # parse the mn results
1028 response = response.split("\r\n")
1029 response = response[len(response)-2]
1030 response = response.split(": ")
1031 response = response[len(response)-1]
1032 response = response.replace("[", "")
1033 response = response.replace("]", "")
1034 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001035
kelvin-onlab7cce9382015-07-17 10:21:03 -07001036 # this is the bandwith two and from the two hosts
1037 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001038
kelvin-onlab7cce9382015-07-17 10:21:03 -07001039 # there should be two elements in the bandwidth list
1040 # ['host1 to host2', 'host2 to host1"]
1041 if len(bandwidth) == 2:
1042 main.log.report(self.name + ": iperf test successful")
1043 return main.TRUE
1044 else:
1045 main.log.error(self.name + ": invalid iperf results")
1046 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -08001047 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -07001048 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -08001049 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001050
GlennRC61321f22015-07-16 13:36:54 -07001051 except pexpect.TIMEOUT:
1052 main.log.error( self.name + ": TIMEOUT exception found")
1053 main.log.error( self.name + ": Exception: Cannot connect to iperf on port 5001" )
1054 return main.FALSE
1055
Jon Hallfbc828e2015-01-06 17:30:19 -08001056 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001057 main.log.error( self.name + ": EOF exception found" )
1058 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001059 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001060 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001061
1062 def iperfudpAll(self, hosts, bandwidth="10M"):
1063 '''
1064 Runs the iperfudp function with a given set of hosts and specified
1065 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001066
GlennRC61321f22015-07-16 13:36:54 -07001067 @param:
1068 bandwidth: the targeted bandwidth, in megabits ('M')
1069 '''
1070 for host1 in hosts:
1071 for host2 in hosts:
1072 if host1 != host2:
1073 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1074 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1075
1076 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1077
kelvin-onlab7cce9382015-07-17 10:21:03 -07001078 '''
1079 Creates an iperf UDP test with a specific bandwidth.
1080 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001081
kelvin-onlab7cce9382015-07-17 10:21:03 -07001082 @param:
1083 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1084 '''
1085 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1086 try:
1087 # setup the mininet command
1088 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1089 self.handle.sendline(cmd)
1090 self.handle.expect("mininet>")
1091 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001092
kelvin-onlab7cce9382015-07-17 10:21:03 -07001093 # check if there are in results in the mininet response
1094 if "Results:" in response:
1095 main.log.report(self.name + ": iperfudp test completed")
1096 # parse the results
1097 response = response.split("\r\n")
1098 response = response[len(response)-2]
1099 response = response.split(": ")
1100 response = response[len(response)-1]
1101 response = response.replace("[", "")
1102 response = response.replace("]", "")
1103 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001104
kelvin-onlab7cce9382015-07-17 10:21:03 -07001105 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001106
kelvin-onlab7cce9382015-07-17 10:21:03 -07001107 # check to see if there are at least three entries
1108 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1109 if len(mnBandwidth) == 3:
1110 # if one entry is blank then something is wrong
1111 for item in mnBandwidth:
1112 if item == "":
1113 main.log.error(self.name + ": Could not parse iperf output")
1114 main.log.error(self.name + ": invalid iperfudp results")
1115 return main.FALSE
1116 # otherwise results are vaild
1117 main.log.report(self.name + ": iperfudp test successful")
1118 return main.TRUE
1119 else:
1120 main.log.error(self.name + ": invalid iperfudp results")
1121 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001122
kelvin-onlab7cce9382015-07-17 10:21:03 -07001123 except pexpect.EOF:
1124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
1126 main.cleanup()
1127 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001128
Jon Hall7eb38402015-01-08 17:19:54 -08001129 def nodes( self ):
1130 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001131 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001132 response = self.execute(
1133 cmd='nodes',
1134 prompt='mininet>',
1135 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001136 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001137 main.log.error( self.name + ": EOF exception found" )
1138 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001139 main.cleanup()
1140 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001141 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001142
Jon Hall7eb38402015-01-08 17:19:54 -08001143 def pingpair( self ):
1144 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001145 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001146 response = self.execute(
1147 cmd='pingpair',
1148 prompt='mininet>',
1149 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001150 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001151 main.log.error( self.name + ": EOF exception found" )
1152 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001153 main.cleanup()
1154 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001155
Jon Hall7eb38402015-01-08 17:19:54 -08001156 if re.search( ',\s0\%\spacket\sloss', response ):
1157 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -07001159 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001160 else:
1161 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -07001163 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001164
Jon Hall7eb38402015-01-08 17:19:54 -08001165 def link( self, **linkargs ):
1166 """
1167 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001168 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001169 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1170 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1171 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1172 main.log.info(
1173 "Bring link between '" +
1174 end1 +
1175 "' and '" +
1176 end2 +
1177 "' '" +
1178 option +
1179 "'" )
1180 command = "link " + \
1181 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001182 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001183 self.handle.sendline( command )
1184 self.handle.expect( "mininet>" )
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()
adminbae64d82013-08-01 10:50:15 -07001190 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001191
Jon Hall7eb38402015-01-08 17:19:54 -08001192 def yank( self, **yankargs ):
1193 """
1194 yank a mininet switch interface to a host"""
1195 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001196 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
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 ) + '.detach("' + 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()
adminaeedddd2013-08-02 15:14:15 -07001210 return main.TRUE
1211
Jon Hall7eb38402015-01-08 17:19:54 -08001212 def plug( self, **plugargs ):
1213 """
1214 plug the yanked mininet switch interface to a switch"""
1215 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001216 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001217 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1218 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1219 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001220 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001221 response = self.execute(
1222 cmd=command,
1223 prompt="mininet>",
1224 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001225 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001226 main.log.error( self.name + ": EOF exception found" )
1227 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001228 main.cleanup()
1229 main.exit()
adminbae64d82013-08-01 10:50:15 -07001230 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001231
Jon Hall7eb38402015-01-08 17:19:54 -08001232 def dpctl( self, **dpctlargs ):
1233 """
1234 Run dpctl command on all switches."""
1235 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001236 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001237 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1238 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1239 command = "dpctl " + cmd + " " + str( cmdargs )
1240 try:
1241 response = self.execute(
1242 cmd=command,
1243 prompt="mininet>",
1244 timeout=10 )
1245 except pexpect.EOF:
1246 main.log.error( self.name + ": EOF exception found" )
1247 main.log.error( self.name + ": " + self.handle.before )
1248 main.cleanup()
1249 main.exit()
1250 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001253 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001254 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 fileInput = path + '/lib/Mininet/INSTALL'
1256 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001257 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001259 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001260 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001261 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001262 return version
adminbae64d82013-08-01 10:50:15 -07001263
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001265 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001266 Parameters:
1267 sw: The name of an OVS switch. Example "s1"
1268 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001269 The output of the command from the mininet cli
1270 or main.FALSE on timeout"""
1271 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001272 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001273 response = self.execute(
1274 cmd=command,
1275 prompt="mininet>",
1276 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001277 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001278 return response
admin2a9548d2014-06-17 14:08:07 -07001279 else:
1280 return main.FALSE
1281 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001282 main.log.error( self.name + ": EOF exception found" )
1283 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001284 main.cleanup()
1285 main.exit()
adminbae64d82013-08-01 10:50:15 -07001286
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001287 def assignSwController( self, sw, ip, port="6633", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001288 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001289 Description:
1290 Assign switches to the controllers ( for ovs use only )
1291 Required:
1292 sw - Name of the switch. This can be a list or a string.
1293 ip - Ip addresses of controllers. This can be a list or a string.
1294 Optional:
1295 port - ONOS use port 6633, if no list of ports is passed, then
1296 the all the controller will use 6633 as their port number
1297 ptcp - ptcp number, This can be a string or a list that has
1298 the same length as switch. This is optional and not required
1299 when using ovs switches.
1300 NOTE: If switches and ptcp are given in a list type they should have the
1301 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1302 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001303
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001304 Return:
1305 Returns main.TRUE if mininet correctly assigned switches to
1306 controllers, otherwise it will return main.FALSE or an appropriate
1307 exception(s)
1308 """
1309 assignResult = main.TRUE
1310 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001311 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001312 command = "sh ovs-vsctl set-controller "
1313 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001314 try:
1315 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001316 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001317 if isinstance( port, types.StringType ) or \
1318 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001319 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001320 elif isinstance( port, types.ListType ):
1321 main.log.error( self.name + ": Only one controller " +
1322 "assigned and a list of ports has" +
1323 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001324 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001325 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001326 main.log.error( self.name + ": Invalid controller port " +
1327 "number. Please specify correct " +
1328 "controller port" )
1329 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001330
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001331 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001332 if isinstance( port, types.StringType ) or \
1333 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001334 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001335 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1336 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001337 elif isinstance( port, types.ListType ):
1338 if ( len( ip ) != len( port ) ):
1339 main.log.error( self.name + ": Port list = " +
1340 str( len( port ) ) +
1341 "should be the same as controller" +
1342 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001343 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001344 else:
1345 onosIp = ""
1346 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001347 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1348 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001349 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001350 main.log.error( self.name + ": Invalid controller port " +
1351 "number. Please specify correct " +
1352 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001353 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001354 else:
1355 main.log.error( self.name + ": Invalid ip address" )
1356 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001357
1358 if isinstance( sw, types.StringType ):
1359 command += sw + " "
1360 if ptcp:
1361 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001362 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001363 elif isinstance( ptcp, types.ListType ):
1364 main.log.error( self.name + ": Only one switch is " +
1365 "being set and multiple PTCP is " +
1366 "being passed " )
1367 else:
1368 main.log.error( self.name + ": Invalid PTCP" )
1369 ptcp = ""
1370 command += onosIp
1371 commandList.append( command )
1372
1373 elif isinstance( sw, types.ListType ):
1374 if ptcp:
1375 if isinstance( ptcp, types.ListType ):
1376 if len( ptcp ) != len( sw ):
1377 main.log.error( self.name + ": PTCP length = " +
1378 str( len( ptcp ) ) +
1379 " is not the same as switch" +
1380 " length = " +
1381 str( len( sw ) ) )
1382 return main.FALSE
1383 else:
1384 for switch, ptcpNum in zip( sw, ptcp ):
1385 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001386 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001387 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001388 tempCmd += onosIp
1389 commandList.append( tempCmd )
1390 else:
1391 main.log.error( self.name + ": Invalid PTCP" )
1392 return main.FALSE
1393 else:
1394 for switch in sw:
1395 tempCmd = "sh ovs-vsctl set-controller "
1396 tempCmd += switch + " " + onosIp
1397 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001398 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001399 main.log.error( self.name + ": Invalid switch type " )
1400 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001401
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001402 for cmd in commandList:
1403 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001404 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001405 except pexpect.TIMEOUT:
1406 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1407 return main.FALSE
1408 except pexpect.EOF:
1409 main.log.error( self.name + ": EOF exception found" )
1410 main.log.error( self.name + ": " + self.handle.before )
1411 main.cleanup()
1412 main.exit()
1413 return main.TRUE
1414 except Exception:
1415 main.log.exception( self.name + ": Uncaught exception!" )
1416 main.cleanup()
1417 main.exit()
adminbae64d82013-08-01 10:50:15 -07001418
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001420 """
1421 Removes the controller target from sw"""
1422 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001423 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001424 response = self.execute(
1425 cmd=command,
1426 prompt="mininet>",
1427 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001428 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 main.log.error( self.name + ": EOF exception found" )
1430 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001431 main.cleanup()
1432 main.exit()
1433 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001434 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001435
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001437 """
Jon Hallb1290e82014-11-18 16:17:48 -05001438 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001439 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001440 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001441 NOTE: cannot currently specify what type of switch
1442 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001443 sw = name of the new switch as a string
1444 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001445 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001446 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001447 """
1448 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001449 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001450 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001451 response = self.execute(
1452 cmd=command,
1453 prompt="mininet>",
1454 timeout=10 )
1455 if re.search( "already exists!", response ):
1456 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001457 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001458 elif re.search( "Error", response ):
1459 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001460 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001461 elif re.search( "usage:", response ):
1462 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001463 return main.FALSE
1464 else:
1465 return main.TRUE
1466 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001467 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001468 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001469 main.cleanup()
1470 main.exit()
1471
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001473 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001474 delete a switch from the mininet topology
1475 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001476 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001477 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001478 sw = name of the switch as a string
1479 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001480 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001481 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001482 response = self.execute(
1483 cmd=command,
1484 prompt="mininet>",
1485 timeout=10 )
1486 if re.search( "no switch named", response ):
1487 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001488 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001489 elif re.search( "Error", response ):
1490 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001491 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001492 elif re.search( "usage:", response ):
1493 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001494 return main.FALSE
1495 else:
1496 return main.TRUE
1497 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001498 main.log.error( self.name + ": EOF exception found" )
1499 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001500 main.cleanup()
1501 main.exit()
1502
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001504 """
1505 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001506 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001507 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001508 NOTE: cannot currently specify what type of link
1509 required params:
1510 node1 = the string node name of the first endpoint of the link
1511 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001512 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001513 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001514 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001515 response = self.execute(
1516 cmd=command,
1517 prompt="mininet>",
1518 timeout=10 )
1519 if re.search( "doesnt exist!", response ):
1520 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001521 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001522 elif re.search( "Error", response ):
1523 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001524 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001525 elif re.search( "usage:", response ):
1526 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001527 return main.FALSE
1528 else:
1529 return main.TRUE
1530 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001531 main.log.error( self.name + ": EOF exception found" )
1532 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001533 main.cleanup()
1534 main.exit()
1535
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001537 """
1538 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001539 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001540 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001541 required params:
1542 node1 = the string node name of the first endpoint of the link
1543 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001544 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001545 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001546 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001547 response = self.execute(
1548 cmd=command,
1549 prompt="mininet>",
1550 timeout=10 )
1551 if re.search( "no node named", response ):
1552 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001553 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001554 elif re.search( "Error", response ):
1555 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001556 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001557 elif re.search( "usage:", response ):
1558 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001559 return main.FALSE
1560 else:
1561 return main.TRUE
1562 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001563 main.log.error( self.name + ": EOF exception found" )
1564 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001565 main.cleanup()
1566 main.exit()
1567
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001569 """
Jon Hallb1290e82014-11-18 16:17:48 -05001570 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001571 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001572 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001573 NOTE: cannot currently specify what type of host
1574 required params:
1575 hostname = the string hostname
1576 optional key-value params
1577 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001578 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001579 """
1580 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001581 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001582 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001583 response = self.execute(
1584 cmd=command,
1585 prompt="mininet>",
1586 timeout=10 )
1587 if re.search( "already exists!", response ):
1588 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001589 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001590 elif re.search( "doesnt exists!", response ):
1591 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001592 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001593 elif re.search( "Error", response ):
1594 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001595 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001596 elif re.search( "usage:", response ):
1597 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001598 return main.FALSE
1599 else:
1600 return main.TRUE
1601 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001602 main.log.error( self.name + ": EOF exception found" )
1603 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001604 main.cleanup()
1605 main.exit()
1606
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001608 """
1609 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001610 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001611 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001612 NOTE: this uses a custom mn function
1613 required params:
1614 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001615 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001616 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001617 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001618 response = self.execute(
1619 cmd=command,
1620 prompt="mininet>",
1621 timeout=10 )
1622 if re.search( "no host named", response ):
1623 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001624 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001625 elif re.search( "Error", response ):
1626 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001627 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001628 elif re.search( "usage:", response ):
1629 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001630 return main.FALSE
1631 else:
1632 return main.TRUE
1633 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001634 main.log.error( self.name + ": EOF exception found" )
1635 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001636 main.cleanup()
1637 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001638
Jon Hall7eb38402015-01-08 17:19:54 -08001639 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001640 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001641 Called at the end of the test to stop the mininet and
1642 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001643 """
Jon Halld80cc142015-07-06 13:36:05 -07001644 self.handle.sendline( '' )
Jon Halld61331b2015-02-17 16:35:47 -08001645 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -07001646 timeout=2 )
Jon Hall390696c2015-05-05 17:13:41 -07001647 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001648 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001649 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001650 elif i == 1:
1651 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001652 # print "Disconnecting Mininet"
1653 if self.handle:
1654 self.handle.sendline( "exit" )
1655 self.handle.expect( "exit" )
1656 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001657 else:
1658 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001659 return response
1660
Jon Halld80cc142015-07-06 13:36:05 -07001661 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001662 """
Jon Hall21270ac2015-02-16 17:59:55 -08001663 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001664 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001665 main.FALSE if the pexpect handle does not exist.
1666
Jon Halld61331b2015-02-17 16:35:47 -08001667 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001668 """
Jon Halld61331b2015-02-17 16:35:47 -08001669 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001670 response = ''
1671 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001672 try:
Jon Halld80cc142015-07-06 13:36:05 -07001673 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08001674 i = self.handle.expect( [ 'mininet>',
1675 '\$',
1676 pexpect.EOF,
1677 pexpect.TIMEOUT ],
1678 timeout )
1679 if i == 0:
1680 main.log.info( "Exiting mininet..." )
Jon Hall7eb38402015-01-08 17:19:54 -08001681 response = self.execute(
1682 cmd="exit",
1683 prompt="(.*)",
1684 timeout=120 )
Jon Halld80cc142015-07-06 13:36:05 -07001685 main.log.info( self.name + ": Stopped" )
Jon Hall7eb38402015-01-08 17:19:54 -08001686 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001687 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001688
kelvin-onlab56a3f462015-02-06 14:04:43 -08001689 if i == 1:
1690 main.log.info( " Mininet trying to exit while not " +
1691 "in the mininet prompt" )
1692 elif i == 2:
1693 main.log.error( "Something went wrong exiting mininet" )
1694 elif i == 3: # timeout
1695 main.log.error( "Something went wrong exiting mininet " +
1696 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07001697
Hari Krishnab35c6d02015-03-18 11:13:51 -07001698 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07001699 self.handle.sendline( "" )
1700 self.handle.expect( '\$' )
1701 self.handle.sendline(
1702 "sudo kill -9 \`ps -ef | grep \"" +
1703 fileName +
1704 "\" | grep -v grep | awk '{print $2}'\`" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001705 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001706 main.log.error( self.name + ": EOF exception found" )
1707 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001708 main.cleanup()
1709 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001710 else:
1711 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001712 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001713 return response
1714
kelvin-onlabf0594d72015-05-19 17:25:12 -07001715 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001716 """
1717 Description:
1718 Sends arp message from mininet host for hosts discovery
1719 Required:
1720 host - hosts name
1721 Optional:
1722 ip - ip address that does not exist in the network so there would
1723 be no reply.
1724 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001725 if ethDevice:
1726 ethDevice = '-I ' + ethDevice + ' '
Jon Halld80cc142015-07-06 13:36:05 -07001727 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001728 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001729 main.log.warn( "Sending: " + cmd )
1730 self.handle.sendline( cmd )
1731 response = self.handle.before
1732 self.handle.sendline( "" )
1733 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001734 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001735
1736 except pexpect.EOF:
1737 main.log.error( self.name + ": EOF exception found" )
1738 main.log.error( self.name + ": " + self.handle.before )
1739 main.cleanup()
1740 main.exit()
admin07529932013-11-22 14:58:28 -08001741
Jon Hall7eb38402015-01-08 17:19:54 -08001742 def decToHex( self, num ):
1743 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001744
Jon Hall7eb38402015-01-08 17:19:54 -08001745 def getSwitchFlowCount( self, switch ):
1746 """
1747 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001748 if self.handle:
1749 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1750 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001751 response = self.execute(
1752 cmd=cmd,
1753 prompt="mininet>",
1754 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001755 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001758 main.cleanup()
1759 main.exit()
1760 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001761 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001762 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001763 main.log.info(
1764 "Couldn't find flows on switch %s, found: %s" %
1765 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001766 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001767 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001768 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001769 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001770
kelvin-onlabd3b64892015-01-20 13:26:24 -08001771 def checkFlows( self, sw, dumpFormat=None ):
1772 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001773 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001775 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001776 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001777 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001778 response = self.execute(
1779 cmd=command,
1780 prompt="mininet>",
1781 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001782 return response
1783 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001784 main.log.error( self.name + ": EOF exception found" )
1785 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001786 main.cleanup()
1787 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001788
Jon Hall9043c902015-07-30 14:23:44 -07001789 def getFlowTable( self, protoVersion, sw ):
1790 """
1791 Returns certain fields of an OVS flow table. Will force output to
1792 either OF 1.0 or 1.3 format for consistency.
1793
1794 TODO add option to look at cookies. ignoring them for now
1795
1796 NOTE: Use format to force consistent flow table output across
1797 versions
1798 """
1799 try:
1800 self.handle.sendline( "" )
1801 self.handle.expect( "mininet>" )
1802 command = "sh ovs-ofctl dump-flows " + sw
1803 if protoVersion == 1.0:
1804 command += " -F OpenFlow10-table_id | awk '{OFS=\",\" ;" +\
1805 " print $1 $3 $6 $7 $8}' | "
1806 elif protoVersion == 1.3:
1807 command += " -O OpenFlow13 | awk '{OFS=\",\" ;" +\
1808 " print $1 $3 $6 $7}' | "
1809 else:
1810 main.log.error(
1811 "Unknown protoVersion in getFlowTable(). given: (" +
1812 str( type( protoVersion ) ) +
1813 ") '" + str( protoVersion ) + "'" )
1814 return None
1815 command += "cut -d ',' -f 2- | sort -n -k1 -r"
1816 self.handle.sendline( command )
1817 self.handle.expect( "sort" )
1818 self.handle.expect( "OFPST_FLOW" )
1819 response = self.handle.before
1820 return response
1821 except pexpect.EOF:
1822 main.log.error( self.name + ": EOF exception found" )
1823 main.log.error( self.name + ": " + self.handle.before )
1824 main.cleanup()
1825 main.exit()
1826 except pexpect.TIMEOUT:
1827 main.log.exception( self.name + ": Timeout exception: " )
1828 return None
1829
1830 def flowComp( self, flow1, flow2 ):
1831 if flow1 == flow2:
1832 return main.TRUE
1833 else:
1834 main.log.info( "Flow tables do not match, printing tables:" )
1835 main.log.info( "Flow Table 1:" )
1836 main.log.info( flow1 )
1837 main.log.info( "Flow Table 2:" )
1838 main.log.info( flow2 )
1839 return main.FALSE
1840
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001842 """
Jon Hallefbd9792015-03-05 16:11:36 -08001843 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001844 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001845 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001846 self.handle.sendline( "" )
1847 self.handle.expect( "mininet>" )
1848 self.handle.sendline(
1849 "sh sudo tcpdump -n -i " +
1850 intf +
1851 " " +
1852 port +
1853 " -w " +
1854 filename.strip() +
1855 " &" )
1856 self.handle.sendline( "" )
1857 i = self.handle.expect( [ 'No\ssuch\device',
1858 'listening\son',
1859 pexpect.TIMEOUT,
1860 "mininet>" ],
1861 timeout=10 )
1862 main.log.warn( self.handle.before + self.handle.after )
1863 self.handle.sendline( "" )
1864 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001865 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001866 main.log.error(
1867 self.name +
1868 ": tcpdump - No such device exists. " +
1869 "tcpdump attempted on: " +
1870 intf )
admin2a9548d2014-06-17 14:08:07 -07001871 return main.FALSE
1872 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001873 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001874 return main.TRUE
1875 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001876 main.log.error(
1877 self.name +
1878 ": tcpdump command timed out! Check interface name," +
1879 " given interface was: " +
1880 intf )
admin2a9548d2014-06-17 14:08:07 -07001881 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001882 elif i == 3:
1883 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001884 return main.TRUE
1885 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001886 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001887 return main.FALSE
1888 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001889 main.log.error( self.name + ": EOF exception found" )
1890 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001891 main.cleanup()
1892 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001893 except Exception:
1894 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001895 main.cleanup()
1896 main.exit()
1897
kelvin-onlabd3b64892015-01-20 13:26:24 -08001898 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001899 """
1900 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001901 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001902 self.handle.sendline( "sh sudo pkill tcpdump" )
1903 self.handle.expect( "mininet>" )
1904 self.handle.sendline( "" )
1905 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001906 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001907 main.log.error( self.name + ": EOF exception found" )
1908 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001909 main.cleanup()
1910 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001911 except Exception:
1912 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001913 main.cleanup()
1914 main.exit()
1915
Jon Halld80cc142015-07-06 13:36:05 -07001916 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001917 """
1918 Read ports from a Mininet switch.
1919
1920 Returns a json structure containing information about the
1921 ports of the given switch.
1922 """
1923 response = self.getInterfaces( nodeName )
1924 # TODO: Sanity check on response. log if no such switch exists
1925 ports = []
1926 for line in response.split( "\n" ):
1927 if not line.startswith( "name=" ):
1928 continue
1929 portVars = {}
1930 for var in line.split( "," ):
1931 key, value = var.split( "=" )
1932 portVars[ key ] = value
1933 isUp = portVars.pop( 'enabled', "True" )
1934 isUp = "True" in isUp
1935 if verbose:
1936 main.log.info( "Reading switch port %s(%s)" %
1937 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
1938 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001939 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001940 mac = None
1941 ips = []
1942 ip = portVars[ 'ip' ]
1943 if ip == 'None':
1944 ip = None
1945 ips.append( ip )
1946 name = portVars[ 'name' ]
1947 if name == 'None':
1948 name = None
1949 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
1950 if name == 'lo':
1951 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
1952 else:
1953 portNo = re.search( portRe, name ).group( 'port' )
1954 ports.append( { 'of_port': portNo,
1955 'mac': str( mac ).replace( '\'', '' ),
1956 'name': name,
1957 'ips': ips,
1958 'enabled': isUp } )
1959 return ports
1960
Jon Halld80cc142015-07-06 13:36:05 -07001961 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001962 """
1963 Read switches from Mininet.
1964
1965 Returns a dictionary whose keys are the switch names and the value is
1966 a dictionary containing information about the switch.
1967 """
Jon Halla22481b2015-07-28 17:46:01 -07001968 # NOTE: To support new Mininet switch classes, just append the new
1969 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07001970
Jon Halla22481b2015-07-28 17:46:01 -07001971 # Regex patterns to parse 'dump' output
1972 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07001973 # <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 -07001974 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07001975 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
1976 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
1977 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
1978 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
1979 swRE = r"<(?P<class>" + switchClasses + r")" +\
1980 r"(?P<options>\{.*\})?\s" +\
1981 r"(?P<name>[^:]+)\:\s" +\
1982 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
1983 r"\spid=(?P<pid>(\d)+)"
Jon Hallafa8a472015-06-12 14:02:42 -07001984 # Update mn port info
1985 self.update()
Jon Halld80cc142015-07-06 13:36:05 -07001986 output = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001987 dump = self.dump().split( "\n" )
1988 for line in dump:
Jon Halla22481b2015-07-28 17:46:01 -07001989 result = re.search( swRE, line, re.I )
1990 if result:
Jon Hallafa8a472015-06-12 14:02:42 -07001991 name = result.group( 'name' )
1992 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
Jon Halla22481b2015-07-28 17:46:01 -07001993 pid = result.group( 'pid' )
1994 swClass = result.group( 'class' )
1995 options = result.group( 'options' )
Jon Hallafa8a472015-06-12 14:02:42 -07001996 if verbose:
1997 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
1998 ports = self.getPorts( name )
Jon Halla22481b2015-07-28 17:46:01 -07001999 output[ name ] = { "dpid": dpid,
2000 "ports": ports,
2001 "swClass": swClass,
2002 "pid": pid,
2003 "options": options }
Jon Hallafa8a472015-06-12 14:02:42 -07002004 return output
2005
Jon Halld80cc142015-07-06 13:36:05 -07002006 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07002007 """
2008 Read hosts from Mininet.
2009
2010 Returns a dictionary whose keys are the host names and the value is
2011 a dictionary containing information about the host.
2012 """
2013 # Regex patterns to parse dump output
2014 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07002015 # <Host h1: pid=12725>
2016 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
2017 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
2018 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07002019 # NOTE: Does not correctly match hosts with multi-links
2020 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
2021 # FIXME: Fix that
kelvin-onlabd48a68c2015-07-13 16:01:36 -07002022 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Jon Halld80cc142015-07-06 13:36:05 -07002023 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
Jon Hallafa8a472015-06-12 14:02:42 -07002024 # update mn port info
2025 self.update()
2026 # Get mininet dump
2027 dump = self.dump().split( "\n" )
Jon Hall5b0120a2015-06-12 17:35:53 -07002028 hosts = {}
Jon Hallafa8a472015-06-12 14:02:42 -07002029 for line in dump:
kelvin-onlabd48a68c2015-07-13 16:01:36 -07002030 if "Host" in line :
Jon Hallafa8a472015-06-12 14:02:42 -07002031 result = re.search( hostRE, line )
2032 name = result.group( 'name' )
2033 interfaces = []
2034 response = self.getInterfaces( name )
2035 # Populate interface info
2036 for line in response.split( "\n" ):
2037 if line.startswith( "name=" ):
2038 portVars = {}
2039 for var in line.split( "," ):
2040 key, value = var.split( "=" )
2041 portVars[ key ] = value
2042 isUp = portVars.pop( 'enabled', "True" )
2043 isUp = "True" in isUp
2044 if verbose:
2045 main.log.info( "Reading host port %s(%s)" %
2046 ( portVars[ 'name' ],
2047 portVars[ 'mac' ] ) )
2048 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07002049 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07002050 mac = None
2051 ips = []
2052 ip = portVars[ 'ip' ]
2053 if ip == 'None':
2054 ip = None
2055 ips.append( ip )
2056 intfName = portVars[ 'name' ]
2057 if name == 'None':
2058 name = None
2059 interfaces.append( {
2060 "name": intfName,
2061 "ips": ips,
2062 "mac": str( mac ),
2063 "isUp": isUp } )
Jon Hall5b0120a2015-06-12 17:35:53 -07002064 hosts[ name ] = { "interfaces": interfaces }
Jon Hallafa8a472015-06-12 14:02:42 -07002065 return hosts
2066
2067 def getLinks( self ):
2068 """
2069 Gathers information about current Mininet links. These links may not
2070 be up if one of the ports is down.
2071
2072 Returns a list of dictionaries with link endpoints.
2073
2074 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002075 { 'node1': str( node1 name )
2076 'node2': str( node2 name )
2077 'port1': str( port1 of_port )
2078 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002079 Note: The port number returned is the eth#, not necessarily the of_port
2080 number. In Mininet, for OVS switch, these should be the same. For
2081 hosts, this is just the eth#.
2082 """
2083 self.update()
2084 response = self.links().split( '\n' )
2085
2086 # Examples:
2087 # s1-eth3<->s2-eth1 (OK OK)
2088 # s13-eth3<->h27-eth0 (OK OK)
2089 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2090 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2091 links = []
2092 for line in response:
2093 match = re.search( linkRE, line )
2094 if match:
2095 node1 = match.group( 'node1' )
2096 node2 = match.group( 'node2' )
2097 port1 = match.group( 'port1' )
2098 port2 = match.group( 'port2' )
2099 links.append( { 'node1': node1,
2100 'node2': node2,
2101 'port1': port1,
2102 'port2': port2 } )
2103 return links
2104
2105 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002106 """
2107 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002108 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002109
Jon Hallafa8a472015-06-12 14:02:42 -07002110 Dependencies:
2111 1. numpy - "sudo pip install numpy"
2112 """
2113 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002114 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08002115 mnDPIDs = []
Jon Hallafa8a472015-06-12 14:02:42 -07002116 for swName, switch in switches.iteritems():
Jon Hall7eb38402015-01-08 17:19:54 -08002117 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002118 mnDPIDs.sort()
kelvin-onlabd3b64892015-01-20 13:26:24 -08002119 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08002120 main.log.error(
2121 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07002122 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04002123 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002124 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08002125 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04002126 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08002127 if switch[ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002128 onosDPIDs.append(
2129 switch[ 'id' ].replace(
2130 ":",
2131 '' ).replace(
2132 "of",
2133 '' ).lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002134 onosDPIDs.sort()
Jon Hall3d87d502014-10-17 18:37:42 -04002135
Jon Hall7eb38402015-01-08 17:19:54 -08002136 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002137 switchResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002138 main.log.error( "Switches in MN but not in ONOS:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002139 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002140 main.log.error( str( list1 ) )
2141 main.log.error( "Switches in ONOS but not in MN:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002142 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002143 main.log.error( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002144 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08002145 switchResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002146 finalResults = switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04002147
Jon Hall7eb38402015-01-08 17:19:54 -08002148 # FIXME: this does not look for extra ports in ONOS, only checks that
2149 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002150 portsResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002151
Jon Hall7eb38402015-01-08 17:19:54 -08002152 # PORTS
Jon Hallafa8a472015-06-12 14:02:42 -07002153 for name, mnSwitch in switches.iteritems():
kelvin-onlabd3b64892015-01-20 13:26:24 -08002154 mnPorts = []
2155 onosPorts = []
2156 switchResult = main.TRUE
2157 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002158 if port[ 'enabled' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002159 mnPorts.append( int( port[ 'of_port' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 for onosSwitch in portsJson:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002161 if onosSwitch[ 'device' ][ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002162 if onosSwitch[ 'device' ][ 'id' ].replace(
2163 ':',
2164 '' ).replace(
2165 "of",
2166 '' ) == mnSwitch[ 'dpid' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002167 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002168 if port[ 'isEnabled' ]:
2169 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08002170 # onosPorts.append( 'local' )
2171 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002172 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002173 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002174 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08002175 mnPorts.sort( key=float )
2176 onosPorts.sort( key=float )
Jon Hallafa8a472015-06-12 14:02:42 -07002177
kelvin-onlabd3b64892015-01-20 13:26:24 -08002178 mnPortsLog = mnPorts
2179 onosPortsLog = onosPorts
2180 mnPorts = [ x for x in mnPorts ]
2181 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05002182
Jon Hall7eb38402015-01-08 17:19:54 -08002183 # TODO: handle other reserved port numbers besides LOCAL
2184 # NOTE: Reserved ports
2185 # Local port: -2 in Openflow, ONOS shows 'local', we store as
2186 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002187 for mnPort in mnPortsLog:
2188 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08002189 # don't set results to true here as this is just one of
2190 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08002191 mnPorts.remove( mnPort )
2192 onosPorts.remove( mnPort )
Jon Hallafa8a472015-06-12 14:02:42 -07002193
Jon Hall7eb38402015-01-08 17:19:54 -08002194 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05002195 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08002196 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08002197 if 65534 in mnPorts:
2198 mnPorts.remove( 65534 )
2199 if long( uint64( -2 ) ) in onosPorts:
2200 onosPorts.remove( long( uint64( -2 ) ) )
2201 if len( mnPorts ): # the ports of this switch don't match
2202 switchResult = main.FALSE
2203 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
2204 if len( onosPorts ): # the ports of this switch don't match
2205 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002206 main.log.warn(
2207 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08002208 str( onosPorts ) )
2209 if switchResult == main.FALSE:
Jon Hallafa8a472015-06-12 14:02:42 -07002210 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002211 "The list of ports for switch %s(%s) does not match:" %
Jon Hallafa8a472015-06-12 14:02:42 -07002212 ( name, mnSwitch[ 'dpid' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
2214 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
2215 portsResults = portsResults and switchResult
Jon Hallafa8a472015-06-12 14:02:42 -07002216 finalResults = finalResults and portsResults
2217 return finalResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002218
Jon Hallafa8a472015-06-12 14:02:42 -07002219 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002220 """
2221 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002222 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04002223
Jon Hallafa8a472015-06-12 14:02:42 -07002224 """
Jon Hall7eb38402015-01-08 17:19:54 -08002225 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08002226 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002227 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04002228
Jon Halld80cc142015-07-06 13:36:05 -07002229 mnLinks = []
Jon Hallafa8a472015-06-12 14:02:42 -07002230 for l in links:
2231 try:
2232 node1 = switches[ l[ 'node1' ] ]
2233 node2 = switches[ l[ 'node2' ] ]
2234 enabled = True
2235 for port in node1[ 'ports' ]:
2236 if port[ 'of_port' ] == l[ 'port1' ]:
2237 enabled = enabled and port[ 'enabled' ]
2238 for port in node2[ 'ports' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002239 if port[ 'of_port' ] == l[ 'port2' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002240 enabled = enabled and port[ 'enabled' ]
2241 if enabled:
2242 mnLinks.append( l )
2243 except KeyError:
2244 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002245 if 2 * len( mnLinks ) == len( onos ):
2246 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002247 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002248 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002249 main.log.error(
Jon Hall328ddca2015-01-28 15:57:15 -08002250 "Mininet has " + str( len( mnLinks ) ) +
2251 " bidirectional links and ONOS has " +
2252 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002253
Jon Hall7eb38402015-01-08 17:19:54 -08002254 # iterate through MN links and check if an ONOS link exists in
2255 # both directions
kelvin-onlabd3b64892015-01-20 13:26:24 -08002256 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08002257 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04002258 node1 = None
2259 port1 = None
2260 node2 = None
2261 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08002262 firstDir = main.FALSE
2263 secondDir = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002264 for swName, switch in switches.iteritems():
2265 if swName == link[ 'node1' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002266 node1 = switch[ 'dpid' ]
2267 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002268 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002269 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002270 if node1 is not None and node2 is not None:
2271 break
Jon Hallafa8a472015-06-12 14:02:42 -07002272 if swName == link[ 'node2' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002273 node2 = switch[ 'dpid' ]
2274 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002275 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002276 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002277 if node1 is not None and node2 is not None:
2278 break
2279
kelvin-onlabd3b64892015-01-20 13:26:24 -08002280 for onosLink in onos:
2281 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002282 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002284 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 onosPort1 = onosLink[ 'src' ][ 'port' ]
2286 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002287
Jon Hall72cf1dc2014-10-20 21:04:50 -04002288 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 if str( onosNode1 ) == str( node1 ) and str(
2290 onosNode2 ) == str( node2 ):
2291 if int( onosPort1 ) == int( port1 ) and int(
2292 onosPort2 ) == int( port2 ):
2293 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002294 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002295 main.log.warn(
2296 'The port numbers do not match for ' +
2297 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002298 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002299 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002300 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002301 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002302 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002303
2304 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08002305 elif ( str( onosNode1 ) == str( node2 ) and
2306 str( onosNode2 ) == str( node1 ) ):
2307 if ( int( onosPort1 ) == int( port2 )
2308 and int( onosPort2 ) == int( port1 ) ):
2309 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002310 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002311 main.log.warn(
2312 'The port numbers do not match for ' +
2313 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002314 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002315 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002316 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002317 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002318 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002319 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04002320 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002321 if not firstDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002322 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002323 'ONOS does not have the link %s/%s -> %s/%s' %
2324 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002325 if not secondDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002326 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002327 'ONOS does not have the link %s/%s -> %s/%s' %
2328 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002329 linkResults = linkResults and firstDir and secondDir
2330 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002331
Jon Hallafa8a472015-06-12 14:02:42 -07002332 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08002333 """
Jon Hallafa8a472015-06-12 14:02:42 -07002334 Compare mn and onos Hosts.
2335 Since Mininet hosts are quiet, ONOS will only know of them when they
2336 speak. For this reason, we will only check that the hosts in ONOS
2337 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08002338
Jon Hallafa8a472015-06-12 14:02:42 -07002339 Arguments:
2340 hostsJson: parsed json object from the onos hosts api
2341 Returns:
2342 """
Jon Hallff6b4b22015-02-23 09:25:15 -08002343 import json
2344 hostResults = main.TRUE
Jon Hallff6b4b22015-02-23 09:25:15 -08002345 for onosHost in hostsJson:
2346 onosMAC = onosHost[ 'mac' ].lower()
2347 match = False
Jon Halld80cc142015-07-06 13:36:05 -07002348 for mnHost, info in hosts.iteritems():
2349 for mnIntf in info[ 'interfaces' ]:
2350 if onosMAC == mnIntf[ 'mac' ].lower():
Jon Hallff6b4b22015-02-23 09:25:15 -08002351 match = True
2352 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002353 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002354 pass # all is well
2355 else:
2356 # misssing ip
Jon Halld80cc142015-07-06 13:36:05 -07002357 main.log.error( "ONOS host " +
2358 onosHost[ 'id' ] +
2359 " has a different IP(" +
Jon Hallafa8a472015-06-12 14:02:42 -07002360 str( onosHost[ 'ipAddresses' ] ) +
2361 ") than the Mininet host(" +
Jon Halld80cc142015-07-06 13:36:05 -07002362 str( ip ) +
2363 ")." )
Jon Hallff6b4b22015-02-23 09:25:15 -08002364 output = json.dumps(
Jon Halld80cc142015-07-06 13:36:05 -07002365 onosHost,
2366 sort_keys=True,
2367 indent=4,
2368 separators=( ',', ': ' ) )
Jon Hallff6b4b22015-02-23 09:25:15 -08002369 main.log.info( output )
2370 hostResults = main.FALSE
2371 if not match:
2372 hostResults = main.FALSE
2373 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2374 "corresponding Mininet host." )
2375 output = json.dumps( onosHost,
2376 sort_keys=True,
2377 indent=4,
2378 separators=( ',', ': ' ) )
2379 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002380 return hostResults
2381
Jon Hallafa8a472015-06-12 14:02:42 -07002382 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002383 """
2384 Returns a list of all hosts
2385 Don't ask questions just use it"""
2386 self.handle.sendline( "" )
2387 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002388
Jon Hall7eb38402015-01-08 17:19:54 -08002389 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2390 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002391
kelvin-onlabd3b64892015-01-20 13:26:24 -08002392 handlePy = self.handle.before
2393 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2394 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002395
Jon Hall7eb38402015-01-08 17:19:54 -08002396 self.handle.sendline( "" )
2397 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002398
kelvin-onlabd3b64892015-01-20 13:26:24 -08002399 hostStr = handlePy.replace( "]", "" )
2400 hostStr = hostStr.replace( "'", "" )
2401 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002402 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002403 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002404
kelvin-onlabd3b64892015-01-20 13:26:24 -08002405 return hostList
adminbae64d82013-08-01 10:50:15 -07002406
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002407 def getSwitch( self ):
2408 """
2409 Returns a list of all switches
2410 Again, don't ask question just use it...
2411 """
2412 # get host list...
2413 hostList = self.getHosts()
2414 # Make host set
2415 hostSet = set( hostList )
2416
2417 # Getting all the nodes in mininet
2418 self.handle.sendline( "" )
2419 self.handle.expect( "mininet>" )
2420
2421 self.handle.sendline( "py [ node.name for node in net.values() ]" )
2422 self.handle.expect( "mininet>" )
2423
2424 handlePy = self.handle.before
2425 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2426 handlePy = handlePy.rstrip()
2427
2428 self.handle.sendline( "" )
2429 self.handle.expect( "mininet>" )
2430
2431 nodesStr = handlePy.replace( "]", "" )
2432 nodesStr = nodesStr.replace( "'", "" )
2433 nodesStr = nodesStr.replace( "[", "" )
2434 nodesStr = nodesStr.replace( " ", "" )
2435 nodesList = nodesStr.split( "," )
2436
2437 nodesSet = set( nodesList )
2438 # discarding default controller(s) node
2439 nodesSet.discard( 'c0' )
2440 nodesSet.discard( 'c1' )
2441 nodesSet.discard( 'c2' )
2442
2443 switchSet = nodesSet - hostSet
2444 switchList = list( switchSet )
2445
2446 return switchList
2447
Jon Hall7eb38402015-01-08 17:19:54 -08002448 def update( self ):
2449 """
2450 updates the port address and status information for
2451 each port in mn"""
2452 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002453 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002454 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002455 self.handle.sendline( "" )
2456 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002457
Jon Hall7eb38402015-01-08 17:19:54 -08002458 self.handle.sendline( "update" )
2459 self.handle.expect( "update" )
2460 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002461
Jon Hall7eb38402015-01-08 17:19:54 -08002462 self.handle.sendline( "" )
2463 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002464
Jon Hallb1290e82014-11-18 16:17:48 -05002465 return main.TRUE
2466 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002467 main.log.error( self.name + ": EOF exception found" )
2468 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002469 main.cleanup()
2470 main.exit()
2471
Jon Halld80cc142015-07-06 13:36:05 -07002472 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07002473 """
2474 Add vlan tag to a host.
2475 Dependencies:
2476 This class depends on the "vlan" package
2477 $ sudo apt-get install vlan
2478 Configuration:
2479 Load the 8021q module into the kernel
2480 $sudo modprobe 8021q
2481
2482 To make this setup permanent:
2483 $ sudo su -c 'echo "8021q" >> /etc/modules'
2484 """
2485 if self.handle:
2486 try:
Jon Halld80cc142015-07-06 13:36:05 -07002487 # get the ip address of the host
2488 main.log.info( "Get the ip address of the host" )
2489 ipaddr = self.getIPAddress( host )
2490 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07002491
Jon Halld80cc142015-07-06 13:36:05 -07002492 # remove IP from interface intf
2493 # Ex: h1 ifconfig h1-eth0 inet 0
2494 main.log.info( "Remove IP from interface " )
2495 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2496 self.handle.sendline( cmd2 )
2497 self.handle.expect( "mininet>" )
2498 response = self.handle.before
2499 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002500
Jon Halld80cc142015-07-06 13:36:05 -07002501 # create VLAN interface
2502 # Ex: h1 vconfig add h1-eth0 100
2503 main.log.info( "Create Vlan" )
2504 cmd3 = host + " vconfig add " + intf + " " + vlan
2505 self.handle.sendline( cmd3 )
2506 self.handle.expect( "mininet>" )
2507 response = self.handle.before
2508 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002509
Jon Halld80cc142015-07-06 13:36:05 -07002510 # assign the host's IP to the VLAN interface
2511 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2512 main.log.info( "Assign the host IP to the vlan interface" )
2513 vintf = intf + "." + vlan
2514 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2515 self.handle.sendline( cmd4 )
2516 self.handle.expect( "mininet>" )
2517 response = self.handle.before
2518 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002519
2520 return main.TRUE
2521 except pexpect.EOF:
2522 main.log.error( self.name + ": EOF exception found" )
2523 main.log.error( self.name + ": " + self.handle.before )
2524 return main.FALSE
2525
adminbae64d82013-08-01 10:50:15 -07002526if __name__ != "__main__":
2527 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002528 sys.modules[ __name__ ] = MininetCliDriver()