blob: e9885774d240d901c544cf6b45fb430530ed1e58 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
Jon Hallbe6dfc42015-01-12 17:37:25 -080021MininetCliDriver is the basic driver which will handle the Mininet functions
22
23Some functions rely on a modified version of Mininet. These functions
24should all be noted in the comments. To get this MN version run these commands
25from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080026 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080027 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080028 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git pull
30
Jon Hall272a4db2015-01-12 17:43:48 -080031
32 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080033changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070034import pexpect
adminbae64d82013-08-01 10:50:15 -070035import re
36import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070037import types
kelvin-onlaba4074292015-07-09 15:19:49 -070038import os
Jon Hall1ccf82c2014-10-15 14:55:16 -040039from math import pow
adminbae64d82013-08-01 10:50:15 -070040from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070041
Jon Hall7eb38402015-01-08 17:19:54 -080042
kelvin-onlab50907142015-04-01 13:37:45 -070043class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080044
45 """
46 MininetCliDriver is the basic driver which will handle
47 the Mininet functions"""
48 def __init__( self ):
49 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070050 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080051 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080052 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070053 self.flag = 0
54
Jon Hall7eb38402015-01-08 17:19:54 -080055 def connect( self, **connectargs ):
56 """
57 Here the main is the TestON instance after creating
58 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080059 try:
60 for key in connectargs:
61 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080062
kelvin-onlaba1484582015-02-02 15:46:20 -080063 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070064
65 try:
66 if os.getenv( str( self.ip_address ) ) != None:
67 self.ip_address = os.getenv( str( self.ip_address ) )
68 else:
69 main.log.info( self.name +
70 ": Trying to connect to " +
71 self.ip_address )
72
73 except KeyError:
74 main.log.info( "Invalid host name," +
75 " connecting to local host instead" )
76 self.ip_address = 'localhost'
77 except Exception as inst:
78 main.log.error( "Uncaught exception: " + str( inst ) )
79
kelvin-onlaba1484582015-02-02 15:46:20 -080080 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070081 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080082 self ).connect(
83 user_name=self.user_name,
84 ip_address=self.ip_address,
85 port=None,
86 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080087
kelvin-onlaba1484582015-02-02 15:46:20 -080088 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080089 main.log.info( "Connection successful to the host " +
90 self.user_name +
91 "@" +
92 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080093 return main.TRUE
94 else:
95 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080096 self.user_name +
97 "@" +
98 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080099 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800100 return main.FALSE
101 except pexpect.EOF:
102 main.log.error( self.name + ": EOF exception found" )
103 main.log.error( self.name + ": " + self.handle.before )
104 main.cleanup()
105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800106 except Exception:
107 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800108 main.cleanup()
109 main.exit()
110
kelvin-onlab10e8d392015-06-03 13:53:45 -0700111 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800112 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700113 Description:
114 Starts Mininet accepts a topology(.py) file and/or an optional
115 argument, to start the mininet, as a parameter.
116 Can also send regular mininet command to load up desired topology.
117 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
118 Options:
119 topoFile = file path for topology file (.py)
120 args = extra option added when starting the topology from the file
121 mnCmd = Mininet command use to start topology
122 Returns:
123 main.TRUE if the mininet starts successfully, main.FALSE
124 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800125 """
Jon Hall7eb38402015-01-08 17:19:54 -0800126 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700127 # make sure old networks are cleaned up
128 main.log.info( self.name +
129 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800130 self.handle.sendline( "sudo mn -c" )
131 i = self.handle.expect( [ 'password\sfor\s',
132 'Cleanup\scomplete',
133 pexpect.EOF,
134 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800135 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800136 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700137 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800138 main.log.info( self.name + ": Sending sudo password" )
139 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800140 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800141 '\$',
142 pexpect.EOF,
143 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800144 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800145 if i == 1:
146 main.log.info( self.name + ": Clean" )
147 elif i == 2:
148 main.log.error( self.name + ": Connection terminated" )
149 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700150 main.log.error( self.name + ": Something while cleaning " +
151 "Mininet took too long... " )
152 # Craft the string to start mininet
153 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700154 if not mnCmd:
155 if topoFile is None or topoFile == '': # If no file is given
156 main.log.info( self.name + ": building fresh Mininet" )
157 cmdString += "mn "
158 if args is None or args == '':
159 # If no args given, use args from .topo file
160 args = self.options[ 'arg1' ] +\
Jon Halld80cc142015-07-06 13:36:05 -0700161 " " + self.options[ 'arg2' ] +\
162 " --mac --controller " +\
163 self.options[ 'controller' ] + " " +\
164 self.options[ 'arg3' ]
kelvin-onlab10e8d392015-06-03 13:53:45 -0700165 else: # else only use given args
166 pass
167 # TODO: allow use of topo args and method args?
168 else: # Use given topology file
Jon Halld80cc142015-07-06 13:36:05 -0700169 main.log.info(
170 "Starting Mininet from topo file " +
171 topoFile )
kelvin-onlab10e8d392015-06-03 13:53:45 -0700172 cmdString += topoFile + " "
173 if args is None:
174 args = ''
175 # TODO: allow use of args from .topo file?
176 cmdString += args
177 else:
178 main.log.info( "Starting Mininet topology using '" + mnCmd +
179 "' command" )
180 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700181 # Send the command and check if network started
182 self.handle.sendline( "" )
183 self.handle.expect( '\$' )
184 main.log.info( "Sending '" + cmdString + "' to " + self.name )
185 self.handle.sendline( cmdString )
186 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800187 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700188 'Exception',
189 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800190 pexpect.EOF,
191 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700192 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800193 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700194 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800195 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800196 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700197 response = str( self.handle.before +
198 self.handle.after )
199 self.handle.expect( '\$' )
200 response += str( self.handle.before +
Jon Halld80cc142015-07-06 13:36:05 -0700201 self.handle.after )
Jon Hall689d8e42015-04-03 13:59:24 -0700202 main.log.error(
203 self.name +
204 ": Launching Mininet failed: " + response )
205 return main.FALSE
206 elif i == 2:
207 self.handle.expect( [ "\n",
208 pexpect.EOF,
209 pexpect.TIMEOUT ],
210 timeout )
211 main.log.info( self.handle.before )
212 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800213 main.log.error( self.name + ": Connection timeout" )
214 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700215 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800216 main.log.error(
217 self.name +
218 ": Something took too long... " )
219 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700220 # Why did we hit this part?
221 main.log.error( "startNet did not return correctly" )
222 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800223 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700224 main.log.error( self.name + ": Connection failed to the host " +
225 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800226 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700227 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800228
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800229 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400230 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800231 # In tree topology, if fanout arg is not given, by default it is 2
232 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400233 fanout = 2
234 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500235 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800236 while( k <= depth - 1 ):
237 count = count + pow( fanout, k )
238 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800240 while( k <= depth - 2 ):
241 # depth-2 gives you only core links and not considering
242 # edge links as seen by ONOS. If all the links including
243 # edge links are required, do depth-1
244 count = count + pow( fanout, k )
245 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800247 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800249
Jon Hall7eb38402015-01-08 17:19:54 -0800250 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800252 # by default it is 1
253 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400254 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 numSwitches = depth
256 numHostsPerSw = fanout
257 totalNumHosts = numSwitches * numHostsPerSw
258 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800259 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800261 topoDict = { "num_switches": int( numSwitches ),
262 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400263 return topoDict
264
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700266 """
267 Calculate the number of switches and links in a topo."""
268 # TODO: combine this function and numSwitchesNlinks
269 argList = self.options[ 'arg1' ].split( "," )
270 topoArgList = argList[ 0 ].split( " " )
271 argList = map( int, argList[ 1: ] )
272 topoArgList = topoArgList[ 1: ] + argList
273
274 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400275 return topoDict
276
Jon Halld80cc142015-07-06 13:36:05 -0700277 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800278 """
279 Verifies the reachability of the hosts using pingall command.
280 Optional parameter timeout allows you to specify how long to
281 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700282 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700283 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700284 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700285 ping
286 acceptableFailed - Set the number of acceptable failed pings for the
287 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800288 Returns:
289 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700290 otherwise main.FALSE
291 """
292 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700293 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700294 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700295 if self.handle:
296 main.log.info(
297 self.name +
298 ": Checking reachabilty to the hosts using pingall" )
299 response = ""
300 failedPings = 0
301 returnValue = main.TRUE
302 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700303 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700304 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700305 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700306 pexpect.EOF,
307 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700308 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700309 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700310 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700311 response += self.handle.before
312 break
313 elif i == 1:
314 response += self.handle.before + self.handle.after
315 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700316 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700317 returnValue = main.FALSE
318 if shortCircuit:
319 main.log.error( self.name +
320 ": Aborting pingall - "
321 + str( failedPings ) +
322 " pings failed" )
323 break
Jon Hall390696c2015-05-05 17:13:41 -0700324 if ( time.time() - startTime ) > timeout:
325 returnValue = main.FALSE
326 main.log.error( self.name +
327 ": Aborting pingall - " +
328 "Function took too long " )
329 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700330 elif i == 2:
331 main.log.error( self.name +
332 ": EOF exception found" )
333 main.log.error( self.name + ": " +
334 self.handle.before )
335 main.cleanup()
336 main.exit()
337 elif i == 3:
338 response += self.handle.before
339 main.log.error( self.name +
340 ": TIMEOUT exception found" )
341 main.log.error( self.name +
342 ": " +
343 str( response ) )
344 # NOTE: Send ctrl-c to make sure pingall is done
345 self.handle.sendline( "\x03" )
346 self.handle.expect( "Interrupt" )
347 self.handle.expect( "mininet>" )
348 break
349 pattern = "Results\:"
350 main.log.info( "Pingall output: " + str( response ) )
351 if re.search( pattern, response ):
352 main.log.info( self.name + ": Pingall finished with "
353 + str( failedPings ) + " failed pings" )
354 return returnValue
355 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700356 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700357 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700358 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700359 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700360 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700361 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700362 main.log.error( self.name + ": Connection failed to the host" )
363 main.cleanup()
364 main.exit()
365 except pexpect.TIMEOUT:
366 if response:
367 main.log.info( "Pingall output: " + str( response ) )
368 main.log.error( self.name + ": pexpect.TIMEOUT found" )
369 return main.FALSE
370 except pexpect.EOF:
371 main.log.error( self.name + ": EOF exception found" )
372 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500373 main.cleanup()
374 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700375
Jon Hall7eb38402015-01-08 17:19:54 -0800376 def fpingHost( self, **pingParams ):
377 """
378 Uses the fping package for faster pinging...
379 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800380 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800381 command = args[ "SRC" ] + \
382 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
383 self.handle.sendline( command )
384 self.handle.expect(
385 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
386 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
387 response = self.handle.before
388 if re.search( ":\s-", response ):
389 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700390 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800391 elif re.search( ":\s\d{1,2}\.\d\d", response ):
392 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700393 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800394 main.log.info( self.name + ": Install fping on mininet machine... " )
395 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700396 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800397
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400398 def pingallHosts( self, hostList, pingType='ipv4' ):
399 """
kelvin-onlab2ff57022015-05-29 10:48:51 -0700400 Ping all specified hosts with a specific ping type
401
402 Acceptable pingTypes:
403 - 'ipv4'
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400404 - 'ipv6'
kelvin-onlab2ff57022015-05-29 10:48:51 -0700405
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700407 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700408
409 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400410 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700411
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400412 Returns main.FALSE if one or more of hosts specified
413 cannot reach each other"""
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400414 if pingType == "ipv4":
kelvin-onlab2ff57022015-05-29 10:48:51 -0700415 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400416 elif pingType == "ipv6":
417 cmd = " ping6 -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400418 else:
419 main.log.warn( "Invalid pingType specified" )
420 return
421
422 try:
423 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700424
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400425 isReachable = main.TRUE
426
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400427 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700428 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400429 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700430 pingList = hostList[ :listIndex ] + \
431 hostList[ ( listIndex + 1 ): ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700432
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400433 for temp in pingList:
434 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700435 pingCmd = str( host ) + cmd + str( temp )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400436 self.handle.sendline( pingCmd )
437 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
438 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
439 response = self.handle.before
440 if re.search( ',\s0\%\spacket\sloss', response ):
Jon Halld80cc142015-07-06 13:36:05 -0700441 main.log.info( str( host ) + " -> " + str( temp ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400442 else:
Jon Halld80cc142015-07-06 13:36:05 -0700443 main.log.info(
444 str( host ) + " -> X (" + str( temp ) + ") "
445 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400446 # One of the host to host pair is unreachable
447 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400448
kelvin-onlab2ff57022015-05-29 10:48:51 -0700449 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400450
451 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()
456
Jon Hall7eb38402015-01-08 17:19:54 -0800457 def pingHost( self, **pingParams ):
458 """
459 Ping from one mininet host to another
460 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800461 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800462 command = args[ "SRC" ] + " ping " + \
463 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700464 try:
Jon Hall61282e32015-03-19 11:34:11 -0700465 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800466 self.handle.sendline( command )
467 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700468 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800469 main.log.error(
470 self.name +
471 ": timeout when waiting for response from mininet" )
472 main.log.error( "response: " + str( self.handle.before ) )
473 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700474 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800475 main.log.error(
476 self.name +
477 ": timeout when waiting for response from mininet" )
478 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700479 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800480 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800481 main.log.error( self.name + ": EOF exception found" )
482 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700483 main.cleanup()
484 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800485 main.log.info( self.name + ": Ping Response: " + response )
486 if re.search( ',\s0\%\spacket\sloss', response ):
487 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800488 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700489 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800490 else:
491 main.log.error(
492 self.name +
493 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800494 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700495 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800496
Jon Hall7eb38402015-01-08 17:19:54 -0800497 def checkIP( self, host ):
498 """
499 Verifies the host's ip configured or not."""
500 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700501 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800502 response = self.execute(
503 cmd=host +
504 " ifconfig",
505 prompt="mininet>",
506 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800507 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800508 main.log.error( self.name + ": EOF exception found" )
509 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700510 main.cleanup()
511 main.exit()
adminbae64d82013-08-01 10:50:15 -0700512
Jon Hall7eb38402015-01-08 17:19:54 -0800513 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800514 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
515 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
516 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
517 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
518 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800519 # pattern = "inet addr:10.0.0.6"
520 if re.search( pattern, response ):
521 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700522 return main.TRUE
523 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800524 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700525 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800526 else:
527 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800528
Jon Hall7eb38402015-01-08 17:19:54 -0800529 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800530 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700531 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800532 response = self.execute(
533 cmd="h1 /usr/sbin/sshd -D&",
534 prompt="mininet>",
535 timeout=10 )
536 response = self.execute(
537 cmd="h4 /usr/sbin/sshd -D&",
538 prompt="mininet>",
539 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700540 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800541 vars( self )[ key ] = connectargs[ key ]
542 response = self.execute(
543 cmd="xterm h1 h4 ",
544 prompt="mininet>",
545 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800546 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700549 main.cleanup()
550 main.exit()
adminbae64d82013-08-01 10:50:15 -0700551 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800552 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700553 if self.flag == 0:
554 self.flag = 1
555 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800556 else:
adminbae64d82013-08-01 10:50:15 -0700557 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800558
kelvin-onlaba1484582015-02-02 15:46:20 -0800559 def moveHost( self, host, oldSw, newSw, ):
560 """
561 Moves a host from one switch to another on the fly
562 Note: The intf between host and oldSw when detached
563 using detach(), will still show up in the 'net'
564 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700565 ( which is correct behavior since the interfaces
566 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800567 """
568 if self.handle:
569 try:
570 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700571 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800572 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800573 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800574 response = self.execute( cmd=cmd,
575 prompt="mininet>",
576 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700577
kelvin-onlaba1484582015-02-02 15:46:20 -0800578 # Determine hostintf and Oldswitchintf
579 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800580 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800581 print "cmd2= ", cmd
582 self.handle.sendline( cmd )
583 self.handle.expect( "mininet>" )
584
shahshreya73537862015-02-11 15:15:24 -0800585 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800586 cmd = "px ipaddr = hintf.IP()"
587 print "cmd3= ", cmd
588 self.handle.sendline( cmd )
589 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800590
591 cmd = "px macaddr = hintf.MAC()"
592 print "cmd3= ", cmd
593 self.handle.sendline( cmd )
594 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700595
kelvin-onlaba1484582015-02-02 15:46:20 -0800596 # Detach interface between oldSw-host
597 cmd = "px " + oldSw + ".detach( sintf )"
598 print "cmd4= ", cmd
599 self.handle.sendline( cmd )
600 self.handle.expect( "mininet>" )
601
602 # Add link between host-newSw
603 cmd = "py net.addLink(" + host + "," + newSw + ")"
604 print "cmd5= ", cmd
605 self.handle.sendline( cmd )
606 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700607
kelvin-onlaba1484582015-02-02 15:46:20 -0800608 # Determine hostintf and Newswitchintf
609 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800610 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800611 print "cmd6= ", cmd
612 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700613 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800614
615 # Attach interface between newSw-host
616 cmd = "px " + newSw + ".attach( sintf )"
617 print "cmd3= ", cmd
618 self.handle.sendline( cmd )
619 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700620
kelvin-onlaba1484582015-02-02 15:46:20 -0800621 # Set ipaddress of the host-newSw interface
622 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
623 print "cmd7 = ", cmd
624 self.handle.sendline( cmd )
625 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800626
627 # Set macaddress of the host-newSw interface
628 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
629 print "cmd8 = ", cmd
630 self.handle.sendline( cmd )
631 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700632
kelvin-onlaba1484582015-02-02 15:46:20 -0800633 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800634 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800635 self.handle.sendline( cmd )
636 self.handle.expect( "mininet>" )
637 print "output = ", self.handle.before
638
639 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800640 cmd = host + " ifconfig"
641 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800642 self.handle.sendline( cmd )
643 self.handle.expect( "mininet>" )
644 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700645
kelvin-onlaba1484582015-02-02 15:46:20 -0800646 return main.TRUE
647 except pexpect.EOF:
648 main.log.error( self.name + ": EOF exception found" )
649 main.log.error( self.name + ": " + self.handle.before )
650 return main.FALSE
651
Jon Hall7eb38402015-01-08 17:19:54 -0800652 def changeIP( self, host, intf, newIP, newNetmask ):
653 """
654 Changes the ip address of a host on the fly
655 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800656 if self.handle:
657 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800658 cmd = host + " ifconfig " + intf + " " + \
659 newIP + " " + 'netmask' + " " + newNetmask
660 self.handle.sendline( cmd )
661 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800662 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800663 main.log.info( "response = " + response )
664 main.log.info(
665 "Ip of host " +
666 host +
667 " changed to new IP " +
668 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800669 return main.TRUE
670 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800671 main.log.error( self.name + ": EOF exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800673 return main.FALSE
674
Jon Hall7eb38402015-01-08 17:19:54 -0800675 def changeDefaultGateway( self, host, newGW ):
676 """
677 Changes the default gateway of a host
678 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800679 if self.handle:
680 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800681 cmd = host + " route add default gw " + newGW
682 self.handle.sendline( cmd )
683 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800684 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800685 main.log.info( "response = " + response )
686 main.log.info(
687 "Default gateway of host " +
688 host +
689 " changed to " +
690 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800691 return main.TRUE
692 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800693 main.log.error( self.name + ": EOF exception found" )
694 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800695 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800696
Jon Hall7eb38402015-01-08 17:19:54 -0800697 def addStaticMACAddress( self, host, GW, macaddr ):
698 """
Jon Hallefbd9792015-03-05 16:11:36 -0800699 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800700 if self.handle:
701 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800702 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
703 cmd = host + " arp -s " + GW + " " + macaddr
704 self.handle.sendline( cmd )
705 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800706 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800707 main.log.info( "response = " + response )
708 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800709 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800710 GW +
711 " changed to " +
712 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800713 return main.TRUE
714 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800717 return main.FALSE
718
Jon Hall7eb38402015-01-08 17:19:54 -0800719 def verifyStaticGWandMAC( self, host ):
720 """
721 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800722 if self.handle:
723 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800724 # h1 arp -an
725 cmd = host + " arp -an "
726 self.handle.sendline( cmd )
727 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800728 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800729 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800730 return main.TRUE
731 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800734 return main.FALSE
735
Jon Hall7eb38402015-01-08 17:19:54 -0800736 def getMacAddress( self, host ):
737 """
738 Verifies the host's ip configured or not."""
739 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700740 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 response = self.execute(
742 cmd=host +
743 " ifconfig",
744 prompt="mininet>",
745 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800746 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 main.log.error( self.name + ": EOF exception found" )
748 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700749 main.cleanup()
750 main.exit()
adminbae64d82013-08-01 10:50:15 -0700751
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700752 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 macAddressSearch = re.search( pattern, response, re.I )
754 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800755 main.log.info(
756 self.name +
757 ": Mac-Address of Host " +
758 host +
759 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 macAddress )
761 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700762 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800763 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700764
Jon Hall7eb38402015-01-08 17:19:54 -0800765 def getInterfaceMACAddress( self, host, interface ):
766 """
767 Return the IP address of the interface on the given host"""
768 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700769 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800770 response = self.execute( cmd=host + " ifconfig " + interface,
771 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800772 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800773 main.log.error( self.name + ": EOF exception found" )
774 main.log.error( self.name + ": " + self.handle.before )
775 main.cleanup()
776 main.exit()
777
778 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800779 macAddressSearch = re.search( pattern, response, re.I )
780 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800781 main.log.info( "No mac address found in %s" % response )
782 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800784 main.log.info(
785 "Mac-Address of " +
786 host +
787 ":" +
788 interface +
789 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 macAddress )
791 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800792 else:
793 main.log.error( "Connection failed to the host" )
794
795 def getIPAddress( self, host ):
796 """
797 Verifies the host's ip configured or not."""
798 if self.handle:
799 try:
800 response = self.execute(
801 cmd=host +
802 " ifconfig",
803 prompt="mininet>",
804 timeout=10 )
805 except pexpect.EOF:
806 main.log.error( self.name + ": EOF exception found" )
807 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700808 main.cleanup()
809 main.exit()
adminbae64d82013-08-01 10:50:15 -0700810
811 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800812 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800813 main.log.info(
814 self.name +
815 ": IP-Address of Host " +
816 host +
817 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 ipAddressSearch.group( 1 ) )
819 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800820 else:
821 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800822
Jon Hall7eb38402015-01-08 17:19:54 -0800823 def getSwitchDPID( self, switch ):
824 """
825 return the datapath ID of the switch"""
826 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700827 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700828 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800829 response = self.execute(
830 cmd=cmd,
831 prompt="mininet>",
832 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800833 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700836 main.cleanup()
837 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800838 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800839 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700840 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800841 main.log.info(
842 "Couldn't find DPID for switch %s, found: %s" %
843 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700844 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800845 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700846 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800847 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700848
Jon Hall7eb38402015-01-08 17:19:54 -0800849 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700850 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800851 self.handle.sendline( "" )
852 self.expect( "mininet>" )
853 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700854 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800855 response = self.execute(
856 cmd=cmd,
857 prompt="mininet>",
858 timeout=10 )
859 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700860 response = self.handle.before
861 return response
862 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800863 main.log.error( self.name + ": EOF exception found" )
864 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700865 main.cleanup()
866 main.exit()
867
Jon Hall7eb38402015-01-08 17:19:54 -0800868 def getInterfaces( self, node ):
869 """
870 return information dict about interfaces connected to the node"""
871 if self.handle:
872 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800873 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700874 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700875 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800876 response = self.execute(
877 cmd=cmd,
878 prompt="mininet>",
879 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800880 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800881 main.log.error( self.name + ": EOF exception found" )
882 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700883 main.cleanup()
884 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700885 return response
886 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700888
Jon Hall7eb38402015-01-08 17:19:54 -0800889 def dump( self ):
890 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700891 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800892 response = self.execute(
893 cmd='dump',
894 prompt='mininet>',
895 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800896 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700899 main.cleanup()
900 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700901 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800902
Jon Hall7eb38402015-01-08 17:19:54 -0800903 def intfs( self ):
904 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700905 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800906 response = self.execute(
907 cmd='intfs',
908 prompt='mininet>',
909 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800910 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700913 main.cleanup()
914 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700915 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800916
Jon Hall7eb38402015-01-08 17:19:54 -0800917 def net( self ):
918 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700919 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800920 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800921 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800922 main.log.error( self.name + ": EOF exception found" )
923 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700924 main.cleanup()
925 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700926 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800927
Jon Hallafa8a472015-06-12 14:02:42 -0700928 def links( self ):
929 main.log.info( self.name + ": List network links" )
930 try:
931 response = self.execute( cmd='links', prompt='mininet>',
932 timeout=10 )
933 except pexpect.EOF:
934 main.log.error( self.name + ": EOF exception found" )
935 main.log.error( self.name + ": " + self.handle.before )
936 main.cleanup()
937 main.exit()
938 return response
939
GlennRC61321f22015-07-16 13:36:54 -0700940 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700941 '''
942 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -0700943
kelvin-onlab7cce9382015-07-17 10:21:03 -0700944 @parm:
945 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
946 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
947 '''
948 for host1 in hosts:
949 for host2 in hosts:
950 if host1 != host2:
951 if self.iperftcp(host1, host2, timeout) == main.FALSE:
952 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
GlennRC61321f22015-07-16 13:36:54 -0700953
954 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700955 '''
956 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
957 are valid.
GlennRC61321f22015-07-16 13:36:54 -0700958
kelvin-onlab7cce9382015-07-17 10:21:03 -0700959 @parm:
960 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
961 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
962 '''
963 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
964 try:
965 # Setup the mininet command
966 cmd1 = 'iperf ' + host1 + " " + host2
967 self.handle.sendline( cmd1 )
968 outcome = self.handle.expect( "mininet>", timeout )
969 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -0700970
kelvin-onlab7cce9382015-07-17 10:21:03 -0700971 # checks if there are results in the mininet response
972 if "Results:" in response:
973 main.log.report(self.name + ": iperf test completed")
974 # parse the mn results
975 response = response.split("\r\n")
976 response = response[len(response)-2]
977 response = response.split(": ")
978 response = response[len(response)-1]
979 response = response.replace("[", "")
980 response = response.replace("]", "")
981 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -0700982
kelvin-onlab7cce9382015-07-17 10:21:03 -0700983 # this is the bandwith two and from the two hosts
984 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -0700985
kelvin-onlab7cce9382015-07-17 10:21:03 -0700986 # there should be two elements in the bandwidth list
987 # ['host1 to host2', 'host2 to host1"]
988 if len(bandwidth) == 2:
989 main.log.report(self.name + ": iperf test successful")
990 return main.TRUE
991 else:
992 main.log.error(self.name + ": invalid iperf results")
993 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800994 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -0700995 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -0800996 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800997
GlennRC61321f22015-07-16 13:36:54 -0700998 except pexpect.TIMEOUT:
999 main.log.error( self.name + ": TIMEOUT exception found")
1000 main.log.error( self.name + ": Exception: Cannot connect to iperf on port 5001" )
1001 return main.FALSE
1002
Jon Hallfbc828e2015-01-06 17:30:19 -08001003 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001004 main.log.error( self.name + ": EOF exception found" )
1005 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001006 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001007 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001008
1009 def iperfudpAll(self, hosts, bandwidth="10M"):
1010 '''
1011 Runs the iperfudp function with a given set of hosts and specified
1012 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001013
GlennRC61321f22015-07-16 13:36:54 -07001014 @param:
1015 bandwidth: the targeted bandwidth, in megabits ('M')
1016 '''
1017 for host1 in hosts:
1018 for host2 in hosts:
1019 if host1 != host2:
1020 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1021 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1022
1023 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1024
kelvin-onlab7cce9382015-07-17 10:21:03 -07001025 '''
1026 Creates an iperf UDP test with a specific bandwidth.
1027 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001028
kelvin-onlab7cce9382015-07-17 10:21:03 -07001029 @param:
1030 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1031 '''
1032 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1033 try:
1034 # setup the mininet command
1035 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1036 self.handle.sendline(cmd)
1037 self.handle.expect("mininet>")
1038 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001039
kelvin-onlab7cce9382015-07-17 10:21:03 -07001040 # check if there are in results in the mininet response
1041 if "Results:" in response:
1042 main.log.report(self.name + ": iperfudp test completed")
1043 # parse the results
1044 response = response.split("\r\n")
1045 response = response[len(response)-2]
1046 response = response.split(": ")
1047 response = response[len(response)-1]
1048 response = response.replace("[", "")
1049 response = response.replace("]", "")
1050 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001051
kelvin-onlab7cce9382015-07-17 10:21:03 -07001052 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001053
kelvin-onlab7cce9382015-07-17 10:21:03 -07001054 # check to see if there are at least three entries
1055 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1056 if len(mnBandwidth) == 3:
1057 # if one entry is blank then something is wrong
1058 for item in mnBandwidth:
1059 if item == "":
1060 main.log.error(self.name + ": Could not parse iperf output")
1061 main.log.error(self.name + ": invalid iperfudp results")
1062 return main.FALSE
1063 # otherwise results are vaild
1064 main.log.report(self.name + ": iperfudp test successful")
1065 return main.TRUE
1066 else:
1067 main.log.error(self.name + ": invalid iperfudp results")
1068 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001069
kelvin-onlab7cce9382015-07-17 10:21:03 -07001070 except pexpect.EOF:
1071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
1073 main.cleanup()
1074 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001075
Jon Hall7eb38402015-01-08 17:19:54 -08001076 def nodes( self ):
1077 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001078 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001079 response = self.execute(
1080 cmd='nodes',
1081 prompt='mininet>',
1082 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001083 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001084 main.log.error( self.name + ": EOF exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001086 main.cleanup()
1087 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001088 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001089
Jon Hall7eb38402015-01-08 17:19:54 -08001090 def pingpair( self ):
1091 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001092 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001093 response = self.execute(
1094 cmd='pingpair',
1095 prompt='mininet>',
1096 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001097 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001098 main.log.error( self.name + ": EOF exception found" )
1099 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001100 main.cleanup()
1101 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001102
Jon Hall7eb38402015-01-08 17:19:54 -08001103 if re.search( ',\s0\%\spacket\sloss', response ):
1104 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -07001106 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001107 else:
1108 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -07001110 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001111
Jon Hall7eb38402015-01-08 17:19:54 -08001112 def link( self, **linkargs ):
1113 """
1114 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001115 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001116 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1117 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1118 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1119 main.log.info(
1120 "Bring link between '" +
1121 end1 +
1122 "' and '" +
1123 end2 +
1124 "' '" +
1125 option +
1126 "'" )
1127 command = "link " + \
1128 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001129 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001130 self.handle.sendline( command )
1131 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001132 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 main.log.error( self.name + ": EOF exception found" )
1134 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001135 main.cleanup()
1136 main.exit()
adminbae64d82013-08-01 10:50:15 -07001137 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001138
Jon Hall7eb38402015-01-08 17:19:54 -08001139 def yank( self, **yankargs ):
1140 """
1141 yank a mininet switch interface to a host"""
1142 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001143 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001144 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1145 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1146 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001147 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001148 response = self.execute(
1149 cmd=command,
1150 prompt="mininet>",
1151 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001152 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001153 main.log.error( self.name + ": EOF exception found" )
1154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001155 main.cleanup()
1156 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001157 return main.TRUE
1158
Jon Hall7eb38402015-01-08 17:19:54 -08001159 def plug( self, **plugargs ):
1160 """
1161 plug the yanked mininet switch interface to a switch"""
1162 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001163 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001164 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1165 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1166 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001167 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001168 response = self.execute(
1169 cmd=command,
1170 prompt="mininet>",
1171 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001172 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001173 main.log.error( self.name + ": EOF exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001175 main.cleanup()
1176 main.exit()
adminbae64d82013-08-01 10:50:15 -07001177 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001178
Jon Hall7eb38402015-01-08 17:19:54 -08001179 def dpctl( self, **dpctlargs ):
1180 """
1181 Run dpctl command on all switches."""
1182 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001183 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001184 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1185 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1186 command = "dpctl " + cmd + " " + str( cmdargs )
1187 try:
1188 response = self.execute(
1189 cmd=command,
1190 prompt="mininet>",
1191 timeout=10 )
1192 except pexpect.EOF:
1193 main.log.error( self.name + ": EOF exception found" )
1194 main.log.error( self.name + ": " + self.handle.before )
1195 main.cleanup()
1196 main.exit()
1197 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001198
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001200 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001201 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 fileInput = path + '/lib/Mininet/INSTALL'
1203 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001204 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001206 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001207 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001208 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001209 return version
adminbae64d82013-08-01 10:50:15 -07001210
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001212 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001213 Parameters:
1214 sw: The name of an OVS switch. Example "s1"
1215 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 The output of the command from the mininet cli
1217 or main.FALSE on timeout"""
1218 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001219 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001220 response = self.execute(
1221 cmd=command,
1222 prompt="mininet>",
1223 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001224 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001225 return response
admin2a9548d2014-06-17 14:08:07 -07001226 else:
1227 return main.FALSE
1228 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001229 main.log.error( self.name + ": EOF exception found" )
1230 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001231 main.cleanup()
1232 main.exit()
adminbae64d82013-08-01 10:50:15 -07001233
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001234 def assignSwController( self, sw, ip, port="6633", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001235 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001236 Description:
1237 Assign switches to the controllers ( for ovs use only )
1238 Required:
1239 sw - Name of the switch. This can be a list or a string.
1240 ip - Ip addresses of controllers. This can be a list or a string.
1241 Optional:
1242 port - ONOS use port 6633, if no list of ports is passed, then
1243 the all the controller will use 6633 as their port number
1244 ptcp - ptcp number, This can be a string or a list that has
1245 the same length as switch. This is optional and not required
1246 when using ovs switches.
1247 NOTE: If switches and ptcp are given in a list type they should have the
1248 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1249 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001250
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001251 Return:
1252 Returns main.TRUE if mininet correctly assigned switches to
1253 controllers, otherwise it will return main.FALSE or an appropriate
1254 exception(s)
1255 """
1256 assignResult = main.TRUE
1257 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001258 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001259 command = "sh ovs-vsctl set-controller "
1260 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001261 try:
1262 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001263 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001264 if isinstance( port, types.StringType ) or \
1265 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001266 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001267 elif isinstance( port, types.ListType ):
1268 main.log.error( self.name + ": Only one controller " +
1269 "assigned and a list of ports has" +
1270 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001271 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001272 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001273 main.log.error( self.name + ": Invalid controller port " +
1274 "number. Please specify correct " +
1275 "controller port" )
1276 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001277
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001278 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001279 if isinstance( port, types.StringType ) or \
1280 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001281 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001282 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1283 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001284 elif isinstance( port, types.ListType ):
1285 if ( len( ip ) != len( port ) ):
1286 main.log.error( self.name + ": Port list = " +
1287 str( len( port ) ) +
1288 "should be the same as controller" +
1289 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001290 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001291 else:
1292 onosIp = ""
1293 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001294 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1295 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001296 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001297 main.log.error( self.name + ": Invalid controller port " +
1298 "number. Please specify correct " +
1299 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001300 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001301 else:
1302 main.log.error( self.name + ": Invalid ip address" )
1303 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001304
1305 if isinstance( sw, types.StringType ):
1306 command += sw + " "
1307 if ptcp:
1308 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001309 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001310 elif isinstance( ptcp, types.ListType ):
1311 main.log.error( self.name + ": Only one switch is " +
1312 "being set and multiple PTCP is " +
1313 "being passed " )
1314 else:
1315 main.log.error( self.name + ": Invalid PTCP" )
1316 ptcp = ""
1317 command += onosIp
1318 commandList.append( command )
1319
1320 elif isinstance( sw, types.ListType ):
1321 if ptcp:
1322 if isinstance( ptcp, types.ListType ):
1323 if len( ptcp ) != len( sw ):
1324 main.log.error( self.name + ": PTCP length = " +
1325 str( len( ptcp ) ) +
1326 " is not the same as switch" +
1327 " length = " +
1328 str( len( sw ) ) )
1329 return main.FALSE
1330 else:
1331 for switch, ptcpNum in zip( sw, ptcp ):
1332 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001333 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001334 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001335 tempCmd += onosIp
1336 commandList.append( tempCmd )
1337 else:
1338 main.log.error( self.name + ": Invalid PTCP" )
1339 return main.FALSE
1340 else:
1341 for switch in sw:
1342 tempCmd = "sh ovs-vsctl set-controller "
1343 tempCmd += switch + " " + onosIp
1344 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001345 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001346 main.log.error( self.name + ": Invalid switch type " )
1347 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001348
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001349 for cmd in commandList:
1350 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001351 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001352 except pexpect.TIMEOUT:
1353 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1354 return main.FALSE
1355 except pexpect.EOF:
1356 main.log.error( self.name + ": EOF exception found" )
1357 main.log.error( self.name + ": " + self.handle.before )
1358 main.cleanup()
1359 main.exit()
1360 return main.TRUE
1361 except Exception:
1362 main.log.exception( self.name + ": Uncaught exception!" )
1363 main.cleanup()
1364 main.exit()
adminbae64d82013-08-01 10:50:15 -07001365
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001367 """
1368 Removes the controller target from sw"""
1369 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001370 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 response = self.execute(
1372 cmd=command,
1373 prompt="mininet>",
1374 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001375 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 main.log.error( self.name + ": EOF exception found" )
1377 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001378 main.cleanup()
1379 main.exit()
1380 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001382
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001384 """
Jon Hallb1290e82014-11-18 16:17:48 -05001385 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001386 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001387 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001388 NOTE: cannot currently specify what type of switch
1389 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001390 sw = name of the new switch as a string
1391 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001392 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001393 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001394 """
1395 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001396 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001397 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001398 response = self.execute(
1399 cmd=command,
1400 prompt="mininet>",
1401 timeout=10 )
1402 if re.search( "already exists!", response ):
1403 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001404 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001405 elif re.search( "Error", response ):
1406 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001407 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001408 elif re.search( "usage:", response ):
1409 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001410 return main.FALSE
1411 else:
1412 return main.TRUE
1413 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001414 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001415 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001416 main.cleanup()
1417 main.exit()
1418
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001420 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001421 delete a switch from the mininet topology
1422 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001423 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001424 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001425 sw = name of the switch as a string
1426 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001427 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001428 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 response = self.execute(
1430 cmd=command,
1431 prompt="mininet>",
1432 timeout=10 )
1433 if re.search( "no switch named", response ):
1434 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001435 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001436 elif re.search( "Error", response ):
1437 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001438 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001439 elif re.search( "usage:", response ):
1440 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001441 return main.FALSE
1442 else:
1443 return main.TRUE
1444 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001445 main.log.error( self.name + ": EOF exception found" )
1446 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001447 main.cleanup()
1448 main.exit()
1449
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001451 """
1452 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001453 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001454 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001455 NOTE: cannot currently specify what type of link
1456 required params:
1457 node1 = the string node name of the first endpoint of the link
1458 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001459 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001460 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001461 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001462 response = self.execute(
1463 cmd=command,
1464 prompt="mininet>",
1465 timeout=10 )
1466 if re.search( "doesnt exist!", response ):
1467 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001468 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001469 elif re.search( "Error", response ):
1470 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001471 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001472 elif re.search( "usage:", response ):
1473 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001474 return main.FALSE
1475 else:
1476 return main.TRUE
1477 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001478 main.log.error( self.name + ": EOF exception found" )
1479 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001480 main.cleanup()
1481 main.exit()
1482
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001484 """
1485 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001486 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001487 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001488 required params:
1489 node1 = the string node name of the first endpoint of the link
1490 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001491 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001492 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001493 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001494 response = self.execute(
1495 cmd=command,
1496 prompt="mininet>",
1497 timeout=10 )
1498 if re.search( "no node named", response ):
1499 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001500 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001501 elif re.search( "Error", response ):
1502 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001503 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001504 elif re.search( "usage:", response ):
1505 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001506 return main.FALSE
1507 else:
1508 return main.TRUE
1509 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001510 main.log.error( self.name + ": EOF exception found" )
1511 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001512 main.cleanup()
1513 main.exit()
1514
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001516 """
Jon Hallb1290e82014-11-18 16:17:48 -05001517 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001518 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001519 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001520 NOTE: cannot currently specify what type of host
1521 required params:
1522 hostname = the string hostname
1523 optional key-value params
1524 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001525 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001526 """
1527 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001528 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001529 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001530 response = self.execute(
1531 cmd=command,
1532 prompt="mininet>",
1533 timeout=10 )
1534 if re.search( "already exists!", response ):
1535 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001536 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001537 elif re.search( "doesnt exists!", response ):
1538 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001539 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001540 elif re.search( "Error", response ):
1541 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001542 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001543 elif re.search( "usage:", response ):
1544 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001545 return main.FALSE
1546 else:
1547 return main.TRUE
1548 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001549 main.log.error( self.name + ": EOF exception found" )
1550 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001551 main.cleanup()
1552 main.exit()
1553
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001555 """
1556 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001557 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001558 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001559 NOTE: this uses a custom mn function
1560 required params:
1561 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001562 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001563 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001564 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001565 response = self.execute(
1566 cmd=command,
1567 prompt="mininet>",
1568 timeout=10 )
1569 if re.search( "no host named", response ):
1570 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001571 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001572 elif re.search( "Error", response ):
1573 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001574 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001575 elif re.search( "usage:", response ):
1576 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001577 return main.FALSE
1578 else:
1579 return main.TRUE
1580 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001581 main.log.error( self.name + ": EOF exception found" )
1582 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001583 main.cleanup()
1584 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001585
Jon Hall7eb38402015-01-08 17:19:54 -08001586 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001587 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001588 Called at the end of the test to stop the mininet and
1589 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001590 """
Jon Halld80cc142015-07-06 13:36:05 -07001591 self.handle.sendline( '' )
Jon Halld61331b2015-02-17 16:35:47 -08001592 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -07001593 timeout=2 )
Jon Hall390696c2015-05-05 17:13:41 -07001594 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001595 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001596 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001597 elif i == 1:
1598 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001599 # print "Disconnecting Mininet"
1600 if self.handle:
1601 self.handle.sendline( "exit" )
1602 self.handle.expect( "exit" )
1603 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001604 else:
1605 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001606 return response
1607
Jon Halld80cc142015-07-06 13:36:05 -07001608 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001609 """
Jon Hall21270ac2015-02-16 17:59:55 -08001610 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001611 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001612 main.FALSE if the pexpect handle does not exist.
1613
Jon Halld61331b2015-02-17 16:35:47 -08001614 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001615 """
Jon Halld61331b2015-02-17 16:35:47 -08001616 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001617 response = ''
1618 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001619 try:
Jon Halld80cc142015-07-06 13:36:05 -07001620 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08001621 i = self.handle.expect( [ 'mininet>',
1622 '\$',
1623 pexpect.EOF,
1624 pexpect.TIMEOUT ],
1625 timeout )
1626 if i == 0:
1627 main.log.info( "Exiting mininet..." )
Jon Hall7eb38402015-01-08 17:19:54 -08001628 response = self.execute(
1629 cmd="exit",
1630 prompt="(.*)",
1631 timeout=120 )
Jon Halld80cc142015-07-06 13:36:05 -07001632 main.log.info( self.name + ": Stopped" )
Jon Hall7eb38402015-01-08 17:19:54 -08001633 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001634 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001635
kelvin-onlab56a3f462015-02-06 14:04:43 -08001636 if i == 1:
1637 main.log.info( " Mininet trying to exit while not " +
1638 "in the mininet prompt" )
1639 elif i == 2:
1640 main.log.error( "Something went wrong exiting mininet" )
1641 elif i == 3: # timeout
1642 main.log.error( "Something went wrong exiting mininet " +
1643 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07001644
Hari Krishnab35c6d02015-03-18 11:13:51 -07001645 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07001646 self.handle.sendline( "" )
1647 self.handle.expect( '\$' )
1648 self.handle.sendline(
1649 "sudo kill -9 \`ps -ef | grep \"" +
1650 fileName +
1651 "\" | grep -v grep | awk '{print $2}'\`" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001652 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001653 main.log.error( self.name + ": EOF exception found" )
1654 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001655 main.cleanup()
1656 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001657 else:
1658 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001659 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001660 return response
1661
kelvin-onlabf0594d72015-05-19 17:25:12 -07001662 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001663 """
1664 Description:
1665 Sends arp message from mininet host for hosts discovery
1666 Required:
1667 host - hosts name
1668 Optional:
1669 ip - ip address that does not exist in the network so there would
1670 be no reply.
1671 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001672 if ethDevice:
1673 ethDevice = '-I ' + ethDevice + ' '
Jon Halld80cc142015-07-06 13:36:05 -07001674 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001675 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001676 main.log.warn( "Sending: " + cmd )
1677 self.handle.sendline( cmd )
1678 response = self.handle.before
1679 self.handle.sendline( "" )
1680 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001681 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001682
1683 except pexpect.EOF:
1684 main.log.error( self.name + ": EOF exception found" )
1685 main.log.error( self.name + ": " + self.handle.before )
1686 main.cleanup()
1687 main.exit()
admin07529932013-11-22 14:58:28 -08001688
Jon Hall7eb38402015-01-08 17:19:54 -08001689 def decToHex( self, num ):
1690 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001691
Jon Hall7eb38402015-01-08 17:19:54 -08001692 def getSwitchFlowCount( self, switch ):
1693 """
1694 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001695 if self.handle:
1696 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1697 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001698 response = self.execute(
1699 cmd=cmd,
1700 prompt="mininet>",
1701 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001702 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001703 main.log.error( self.name + ": EOF exception found" )
1704 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001705 main.cleanup()
1706 main.exit()
1707 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001708 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001709 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001710 main.log.info(
1711 "Couldn't find flows on switch %s, found: %s" %
1712 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001713 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001714 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001715 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001716 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001717
kelvin-onlabd3b64892015-01-20 13:26:24 -08001718 def checkFlows( self, sw, dumpFormat=None ):
1719 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001720 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001721 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001722 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001723 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001724 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001725 response = self.execute(
1726 cmd=command,
1727 prompt="mininet>",
1728 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001729 return response
1730 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001731 main.log.error( self.name + ": EOF exception found" )
1732 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001733 main.cleanup()
1734 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001735
kelvin-onlabd3b64892015-01-20 13:26:24 -08001736 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001737 """
Jon Hallefbd9792015-03-05 16:11:36 -08001738 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001739 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001740 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001741 self.handle.sendline( "" )
1742 self.handle.expect( "mininet>" )
1743 self.handle.sendline(
1744 "sh sudo tcpdump -n -i " +
1745 intf +
1746 " " +
1747 port +
1748 " -w " +
1749 filename.strip() +
1750 " &" )
1751 self.handle.sendline( "" )
1752 i = self.handle.expect( [ 'No\ssuch\device',
1753 'listening\son',
1754 pexpect.TIMEOUT,
1755 "mininet>" ],
1756 timeout=10 )
1757 main.log.warn( self.handle.before + self.handle.after )
1758 self.handle.sendline( "" )
1759 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001760 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001761 main.log.error(
1762 self.name +
1763 ": tcpdump - No such device exists. " +
1764 "tcpdump attempted on: " +
1765 intf )
admin2a9548d2014-06-17 14:08:07 -07001766 return main.FALSE
1767 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001768 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001769 return main.TRUE
1770 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001771 main.log.error(
1772 self.name +
1773 ": tcpdump command timed out! Check interface name," +
1774 " given interface was: " +
1775 intf )
admin2a9548d2014-06-17 14:08:07 -07001776 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001777 elif i == 3:
1778 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001779 return main.TRUE
1780 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001781 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001782 return main.FALSE
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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001788 except Exception:
1789 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001790 main.cleanup()
1791 main.exit()
1792
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001794 """
1795 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001796 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001797 self.handle.sendline( "sh sudo pkill tcpdump" )
1798 self.handle.expect( "mininet>" )
1799 self.handle.sendline( "" )
1800 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001801 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001802 main.log.error( self.name + ": EOF exception found" )
1803 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001804 main.cleanup()
1805 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001806 except Exception:
1807 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001808 main.cleanup()
1809 main.exit()
1810
Jon Halld80cc142015-07-06 13:36:05 -07001811 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001812 """
1813 Read ports from a Mininet switch.
1814
1815 Returns a json structure containing information about the
1816 ports of the given switch.
1817 """
1818 response = self.getInterfaces( nodeName )
1819 # TODO: Sanity check on response. log if no such switch exists
1820 ports = []
1821 for line in response.split( "\n" ):
1822 if not line.startswith( "name=" ):
1823 continue
1824 portVars = {}
1825 for var in line.split( "," ):
1826 key, value = var.split( "=" )
1827 portVars[ key ] = value
1828 isUp = portVars.pop( 'enabled', "True" )
1829 isUp = "True" in isUp
1830 if verbose:
1831 main.log.info( "Reading switch port %s(%s)" %
1832 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
1833 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001834 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001835 mac = None
1836 ips = []
1837 ip = portVars[ 'ip' ]
1838 if ip == 'None':
1839 ip = None
1840 ips.append( ip )
1841 name = portVars[ 'name' ]
1842 if name == 'None':
1843 name = None
1844 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
1845 if name == 'lo':
1846 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
1847 else:
1848 portNo = re.search( portRe, name ).group( 'port' )
1849 ports.append( { 'of_port': portNo,
1850 'mac': str( mac ).replace( '\'', '' ),
1851 'name': name,
1852 'ips': ips,
1853 'enabled': isUp } )
1854 return ports
1855
Jon Halld80cc142015-07-06 13:36:05 -07001856 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001857 """
1858 Read switches from Mininet.
1859
1860 Returns a dictionary whose keys are the switch names and the value is
1861 a dictionary containing information about the switch.
1862 """
Jon Halla22481b2015-07-28 17:46:01 -07001863 # NOTE: To support new Mininet switch classes, just append the new
1864 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07001865
Jon Halla22481b2015-07-28 17:46:01 -07001866 # Regex patterns to parse 'dump' output
1867 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07001868 # <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 -07001869 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07001870 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
1871 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
1872 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
1873 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
1874 swRE = r"<(?P<class>" + switchClasses + r")" +\
1875 r"(?P<options>\{.*\})?\s" +\
1876 r"(?P<name>[^:]+)\:\s" +\
1877 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
1878 r"\spid=(?P<pid>(\d)+)"
Jon Hallafa8a472015-06-12 14:02:42 -07001879 # Update mn port info
1880 self.update()
Jon Halld80cc142015-07-06 13:36:05 -07001881 output = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001882 dump = self.dump().split( "\n" )
1883 for line in dump:
Jon Halla22481b2015-07-28 17:46:01 -07001884 result = re.search( swRE, line, re.I )
1885 if result:
Jon Hallafa8a472015-06-12 14:02:42 -07001886 name = result.group( 'name' )
1887 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
Jon Halla22481b2015-07-28 17:46:01 -07001888 pid = result.group( 'pid' )
1889 swClass = result.group( 'class' )
1890 options = result.group( 'options' )
Jon Hallafa8a472015-06-12 14:02:42 -07001891 if verbose:
1892 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
1893 ports = self.getPorts( name )
Jon Halla22481b2015-07-28 17:46:01 -07001894 output[ name ] = { "dpid": dpid,
1895 "ports": ports,
1896 "swClass": swClass,
1897 "pid": pid,
1898 "options": options }
Jon Hallafa8a472015-06-12 14:02:42 -07001899 return output
1900
Jon Halld80cc142015-07-06 13:36:05 -07001901 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001902 """
1903 Read hosts from Mininet.
1904
1905 Returns a dictionary whose keys are the host names and the value is
1906 a dictionary containing information about the host.
1907 """
1908 # Regex patterns to parse dump output
1909 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07001910 # <Host h1: pid=12725>
1911 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
1912 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
1913 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07001914 # NOTE: Does not correctly match hosts with multi-links
1915 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
1916 # FIXME: Fix that
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001917 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Jon Halld80cc142015-07-06 13:36:05 -07001918 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
Jon Hallafa8a472015-06-12 14:02:42 -07001919 # update mn port info
1920 self.update()
1921 # Get mininet dump
1922 dump = self.dump().split( "\n" )
Jon Hall5b0120a2015-06-12 17:35:53 -07001923 hosts = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001924 for line in dump:
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001925 if "Host" in line :
Jon Hallafa8a472015-06-12 14:02:42 -07001926 result = re.search( hostRE, line )
1927 name = result.group( 'name' )
1928 interfaces = []
1929 response = self.getInterfaces( name )
1930 # Populate interface info
1931 for line in response.split( "\n" ):
1932 if line.startswith( "name=" ):
1933 portVars = {}
1934 for var in line.split( "," ):
1935 key, value = var.split( "=" )
1936 portVars[ key ] = value
1937 isUp = portVars.pop( 'enabled', "True" )
1938 isUp = "True" in isUp
1939 if verbose:
1940 main.log.info( "Reading host port %s(%s)" %
1941 ( portVars[ 'name' ],
1942 portVars[ 'mac' ] ) )
1943 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001944 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001945 mac = None
1946 ips = []
1947 ip = portVars[ 'ip' ]
1948 if ip == 'None':
1949 ip = None
1950 ips.append( ip )
1951 intfName = portVars[ 'name' ]
1952 if name == 'None':
1953 name = None
1954 interfaces.append( {
1955 "name": intfName,
1956 "ips": ips,
1957 "mac": str( mac ),
1958 "isUp": isUp } )
Jon Hall5b0120a2015-06-12 17:35:53 -07001959 hosts[ name ] = { "interfaces": interfaces }
Jon Hallafa8a472015-06-12 14:02:42 -07001960 return hosts
1961
1962 def getLinks( self ):
1963 """
1964 Gathers information about current Mininet links. These links may not
1965 be up if one of the ports is down.
1966
1967 Returns a list of dictionaries with link endpoints.
1968
1969 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07001970 { 'node1': str( node1 name )
1971 'node2': str( node2 name )
1972 'port1': str( port1 of_port )
1973 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07001974 Note: The port number returned is the eth#, not necessarily the of_port
1975 number. In Mininet, for OVS switch, these should be the same. For
1976 hosts, this is just the eth#.
1977 """
1978 self.update()
1979 response = self.links().split( '\n' )
1980
1981 # Examples:
1982 # s1-eth3<->s2-eth1 (OK OK)
1983 # s13-eth3<->h27-eth0 (OK OK)
1984 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
1985 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
1986 links = []
1987 for line in response:
1988 match = re.search( linkRE, line )
1989 if match:
1990 node1 = match.group( 'node1' )
1991 node2 = match.group( 'node2' )
1992 port1 = match.group( 'port1' )
1993 port2 = match.group( 'port2' )
1994 links.append( { 'node1': node1,
1995 'node2': node2,
1996 'port1': port1,
1997 'port2': port2 } )
1998 return links
1999
2000 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002001 """
2002 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002003 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002004
Jon Hallafa8a472015-06-12 14:02:42 -07002005 Dependencies:
2006 1. numpy - "sudo pip install numpy"
2007 """
2008 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002009 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08002010 mnDPIDs = []
Jon Hallafa8a472015-06-12 14:02:42 -07002011 for swName, switch in switches.iteritems():
Jon Hall7eb38402015-01-08 17:19:54 -08002012 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002013 mnDPIDs.sort()
kelvin-onlabd3b64892015-01-20 13:26:24 -08002014 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08002015 main.log.error(
2016 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07002017 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04002018 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002019 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08002020 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04002021 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08002022 if switch[ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002023 onosDPIDs.append(
2024 switch[ 'id' ].replace(
2025 ":",
2026 '' ).replace(
2027 "of",
2028 '' ).lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002029 onosDPIDs.sort()
Jon Hall3d87d502014-10-17 18:37:42 -04002030
Jon Hall7eb38402015-01-08 17:19:54 -08002031 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002032 switchResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002033 main.log.error( "Switches in MN but not in ONOS:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002034 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002035 main.log.error( str( list1 ) )
2036 main.log.error( "Switches in ONOS but not in MN:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002037 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002038 main.log.error( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002039 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08002040 switchResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002041 finalResults = switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04002042
Jon Hall7eb38402015-01-08 17:19:54 -08002043 # FIXME: this does not look for extra ports in ONOS, only checks that
2044 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002045 portsResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002046
Jon Hall7eb38402015-01-08 17:19:54 -08002047 # PORTS
Jon Hallafa8a472015-06-12 14:02:42 -07002048 for name, mnSwitch in switches.iteritems():
kelvin-onlabd3b64892015-01-20 13:26:24 -08002049 mnPorts = []
2050 onosPorts = []
2051 switchResult = main.TRUE
2052 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002053 if port[ 'enabled' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002054 mnPorts.append( int( port[ 'of_port' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002055 for onosSwitch in portsJson:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 if onosSwitch[ 'device' ][ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002057 if onosSwitch[ 'device' ][ 'id' ].replace(
2058 ':',
2059 '' ).replace(
2060 "of",
2061 '' ) == mnSwitch[ 'dpid' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002062 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002063 if port[ 'isEnabled' ]:
2064 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08002065 # onosPorts.append( 'local' )
2066 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002067 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002068 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002069 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08002070 mnPorts.sort( key=float )
2071 onosPorts.sort( key=float )
Jon Hallafa8a472015-06-12 14:02:42 -07002072
kelvin-onlabd3b64892015-01-20 13:26:24 -08002073 mnPortsLog = mnPorts
2074 onosPortsLog = onosPorts
2075 mnPorts = [ x for x in mnPorts ]
2076 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05002077
Jon Hall7eb38402015-01-08 17:19:54 -08002078 # TODO: handle other reserved port numbers besides LOCAL
2079 # NOTE: Reserved ports
2080 # Local port: -2 in Openflow, ONOS shows 'local', we store as
2081 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002082 for mnPort in mnPortsLog:
2083 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08002084 # don't set results to true here as this is just one of
2085 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08002086 mnPorts.remove( mnPort )
2087 onosPorts.remove( mnPort )
Jon Hallafa8a472015-06-12 14:02:42 -07002088
Jon Hall7eb38402015-01-08 17:19:54 -08002089 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05002090 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08002091 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08002092 if 65534 in mnPorts:
2093 mnPorts.remove( 65534 )
2094 if long( uint64( -2 ) ) in onosPorts:
2095 onosPorts.remove( long( uint64( -2 ) ) )
2096 if len( mnPorts ): # the ports of this switch don't match
2097 switchResult = main.FALSE
2098 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
2099 if len( onosPorts ): # the ports of this switch don't match
2100 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002101 main.log.warn(
2102 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08002103 str( onosPorts ) )
2104 if switchResult == main.FALSE:
Jon Hallafa8a472015-06-12 14:02:42 -07002105 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002106 "The list of ports for switch %s(%s) does not match:" %
Jon Hallafa8a472015-06-12 14:02:42 -07002107 ( name, mnSwitch[ 'dpid' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002108 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
2109 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
2110 portsResults = portsResults and switchResult
Jon Hallafa8a472015-06-12 14:02:42 -07002111 finalResults = finalResults and portsResults
2112 return finalResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002113
Jon Hallafa8a472015-06-12 14:02:42 -07002114 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002115 """
2116 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04002118
Jon Hallafa8a472015-06-12 14:02:42 -07002119 """
Jon Hall7eb38402015-01-08 17:19:54 -08002120 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08002121 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002122 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04002123
Jon Halld80cc142015-07-06 13:36:05 -07002124 mnLinks = []
Jon Hallafa8a472015-06-12 14:02:42 -07002125 for l in links:
2126 try:
2127 node1 = switches[ l[ 'node1' ] ]
2128 node2 = switches[ l[ 'node2' ] ]
2129 enabled = True
2130 for port in node1[ 'ports' ]:
2131 if port[ 'of_port' ] == l[ 'port1' ]:
2132 enabled = enabled and port[ 'enabled' ]
2133 for port in node2[ 'ports' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002134 if port[ 'of_port' ] == l[ 'port2' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002135 enabled = enabled and port[ 'enabled' ]
2136 if enabled:
2137 mnLinks.append( l )
2138 except KeyError:
2139 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 if 2 * len( mnLinks ) == len( onos ):
2141 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002142 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002143 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002144 main.log.error(
Jon Hall328ddca2015-01-28 15:57:15 -08002145 "Mininet has " + str( len( mnLinks ) ) +
2146 " bidirectional links and ONOS has " +
2147 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002148
Jon Hall7eb38402015-01-08 17:19:54 -08002149 # iterate through MN links and check if an ONOS link exists in
2150 # both directions
kelvin-onlabd3b64892015-01-20 13:26:24 -08002151 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08002152 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04002153 node1 = None
2154 port1 = None
2155 node2 = None
2156 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08002157 firstDir = main.FALSE
2158 secondDir = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002159 for swName, switch in switches.iteritems():
2160 if swName == link[ 'node1' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002161 node1 = switch[ 'dpid' ]
2162 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002163 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002164 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002165 if node1 is not None and node2 is not None:
2166 break
Jon Hallafa8a472015-06-12 14:02:42 -07002167 if swName == link[ 'node2' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002168 node2 = switch[ 'dpid' ]
2169 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002170 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002171 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002172 if node1 is not None and node2 is not None:
2173 break
2174
kelvin-onlabd3b64892015-01-20 13:26:24 -08002175 for onosLink in onos:
2176 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002177 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002178 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002179 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002180 onosPort1 = onosLink[ 'src' ][ 'port' ]
2181 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002182
Jon Hall72cf1dc2014-10-20 21:04:50 -04002183 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08002184 if str( onosNode1 ) == str( node1 ) and str(
2185 onosNode2 ) == str( node2 ):
2186 if int( onosPort1 ) == int( port1 ) and int(
2187 onosPort2 ) == int( port2 ):
2188 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002189 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002190 main.log.warn(
2191 'The port numbers do not match for ' +
2192 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002193 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002194 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002195 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002196 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002197 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002198
2199 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08002200 elif ( str( onosNode1 ) == str( node2 ) and
2201 str( onosNode2 ) == str( node1 ) ):
2202 if ( int( onosPort1 ) == int( port2 )
2203 and int( onosPort2 ) == int( port1 ) ):
2204 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002205 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002206 main.log.warn(
2207 'The port numbers do not match for ' +
2208 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002209 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002210 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002211 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002212 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002213 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002214 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04002215 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002216 if not firstDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002217 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002218 'ONOS does not have the link %s/%s -> %s/%s' %
2219 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002220 if not secondDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002221 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002222 'ONOS does not have the link %s/%s -> %s/%s' %
2223 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002224 linkResults = linkResults and firstDir and secondDir
2225 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002226
Jon Hallafa8a472015-06-12 14:02:42 -07002227 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08002228 """
Jon Hallafa8a472015-06-12 14:02:42 -07002229 Compare mn and onos Hosts.
2230 Since Mininet hosts are quiet, ONOS will only know of them when they
2231 speak. For this reason, we will only check that the hosts in ONOS
2232 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08002233
Jon Hallafa8a472015-06-12 14:02:42 -07002234 Arguments:
2235 hostsJson: parsed json object from the onos hosts api
2236 Returns:
2237 """
Jon Hallff6b4b22015-02-23 09:25:15 -08002238 import json
2239 hostResults = main.TRUE
Jon Hallff6b4b22015-02-23 09:25:15 -08002240 for onosHost in hostsJson:
2241 onosMAC = onosHost[ 'mac' ].lower()
2242 match = False
Jon Halld80cc142015-07-06 13:36:05 -07002243 for mnHost, info in hosts.iteritems():
2244 for mnIntf in info[ 'interfaces' ]:
2245 if onosMAC == mnIntf[ 'mac' ].lower():
Jon Hallff6b4b22015-02-23 09:25:15 -08002246 match = True
2247 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002248 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002249 pass # all is well
2250 else:
2251 # misssing ip
Jon Halld80cc142015-07-06 13:36:05 -07002252 main.log.error( "ONOS host " +
2253 onosHost[ 'id' ] +
2254 " has a different IP(" +
Jon Hallafa8a472015-06-12 14:02:42 -07002255 str( onosHost[ 'ipAddresses' ] ) +
2256 ") than the Mininet host(" +
Jon Halld80cc142015-07-06 13:36:05 -07002257 str( ip ) +
2258 ")." )
Jon Hallff6b4b22015-02-23 09:25:15 -08002259 output = json.dumps(
Jon Halld80cc142015-07-06 13:36:05 -07002260 onosHost,
2261 sort_keys=True,
2262 indent=4,
2263 separators=( ',', ': ' ) )
Jon Hallff6b4b22015-02-23 09:25:15 -08002264 main.log.info( output )
2265 hostResults = main.FALSE
2266 if not match:
2267 hostResults = main.FALSE
2268 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2269 "corresponding Mininet host." )
2270 output = json.dumps( onosHost,
2271 sort_keys=True,
2272 indent=4,
2273 separators=( ',', ': ' ) )
2274 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002275 return hostResults
2276
Jon Hallafa8a472015-06-12 14:02:42 -07002277 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002278 """
2279 Returns a list of all hosts
2280 Don't ask questions just use it"""
2281 self.handle.sendline( "" )
2282 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002283
Jon Hall7eb38402015-01-08 17:19:54 -08002284 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2285 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002286
kelvin-onlabd3b64892015-01-20 13:26:24 -08002287 handlePy = self.handle.before
2288 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2289 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002290
Jon Hall7eb38402015-01-08 17:19:54 -08002291 self.handle.sendline( "" )
2292 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002293
kelvin-onlabd3b64892015-01-20 13:26:24 -08002294 hostStr = handlePy.replace( "]", "" )
2295 hostStr = hostStr.replace( "'", "" )
2296 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002297 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002298 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002299
kelvin-onlabd3b64892015-01-20 13:26:24 -08002300 return hostList
adminbae64d82013-08-01 10:50:15 -07002301
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002302 def getSwitch( self ):
2303 """
2304 Returns a list of all switches
2305 Again, don't ask question just use it...
2306 """
2307 # get host list...
2308 hostList = self.getHosts()
2309 # Make host set
2310 hostSet = set( hostList )
2311
2312 # Getting all the nodes in mininet
2313 self.handle.sendline( "" )
2314 self.handle.expect( "mininet>" )
2315
2316 self.handle.sendline( "py [ node.name for node in net.values() ]" )
2317 self.handle.expect( "mininet>" )
2318
2319 handlePy = self.handle.before
2320 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2321 handlePy = handlePy.rstrip()
2322
2323 self.handle.sendline( "" )
2324 self.handle.expect( "mininet>" )
2325
2326 nodesStr = handlePy.replace( "]", "" )
2327 nodesStr = nodesStr.replace( "'", "" )
2328 nodesStr = nodesStr.replace( "[", "" )
2329 nodesStr = nodesStr.replace( " ", "" )
2330 nodesList = nodesStr.split( "," )
2331
2332 nodesSet = set( nodesList )
2333 # discarding default controller(s) node
2334 nodesSet.discard( 'c0' )
2335 nodesSet.discard( 'c1' )
2336 nodesSet.discard( 'c2' )
2337
2338 switchSet = nodesSet - hostSet
2339 switchList = list( switchSet )
2340
2341 return switchList
2342
Jon Hall7eb38402015-01-08 17:19:54 -08002343 def update( self ):
2344 """
2345 updates the port address and status information for
2346 each port in mn"""
2347 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002348 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002349 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002350 self.handle.sendline( "" )
2351 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002352
Jon Hall7eb38402015-01-08 17:19:54 -08002353 self.handle.sendline( "update" )
2354 self.handle.expect( "update" )
2355 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002356
Jon Hall7eb38402015-01-08 17:19:54 -08002357 self.handle.sendline( "" )
2358 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002359
Jon Hallb1290e82014-11-18 16:17:48 -05002360 return main.TRUE
2361 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002362 main.log.error( self.name + ": EOF exception found" )
2363 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002364 main.cleanup()
2365 main.exit()
2366
Jon Halld80cc142015-07-06 13:36:05 -07002367 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07002368 """
2369 Add vlan tag to a host.
2370 Dependencies:
2371 This class depends on the "vlan" package
2372 $ sudo apt-get install vlan
2373 Configuration:
2374 Load the 8021q module into the kernel
2375 $sudo modprobe 8021q
2376
2377 To make this setup permanent:
2378 $ sudo su -c 'echo "8021q" >> /etc/modules'
2379 """
2380 if self.handle:
2381 try:
Jon Halld80cc142015-07-06 13:36:05 -07002382 # get the ip address of the host
2383 main.log.info( "Get the ip address of the host" )
2384 ipaddr = self.getIPAddress( host )
2385 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07002386
Jon Halld80cc142015-07-06 13:36:05 -07002387 # remove IP from interface intf
2388 # Ex: h1 ifconfig h1-eth0 inet 0
2389 main.log.info( "Remove IP from interface " )
2390 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2391 self.handle.sendline( cmd2 )
2392 self.handle.expect( "mininet>" )
2393 response = self.handle.before
2394 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002395
Jon Halld80cc142015-07-06 13:36:05 -07002396 # create VLAN interface
2397 # Ex: h1 vconfig add h1-eth0 100
2398 main.log.info( "Create Vlan" )
2399 cmd3 = host + " vconfig add " + intf + " " + vlan
2400 self.handle.sendline( cmd3 )
2401 self.handle.expect( "mininet>" )
2402 response = self.handle.before
2403 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002404
Jon Halld80cc142015-07-06 13:36:05 -07002405 # assign the host's IP to the VLAN interface
2406 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2407 main.log.info( "Assign the host IP to the vlan interface" )
2408 vintf = intf + "." + vlan
2409 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2410 self.handle.sendline( cmd4 )
2411 self.handle.expect( "mininet>" )
2412 response = self.handle.before
2413 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002414
2415 return main.TRUE
2416 except pexpect.EOF:
2417 main.log.error( self.name + ": EOF exception found" )
2418 main.log.error( self.name + ": " + self.handle.before )
2419 return main.FALSE
2420
adminbae64d82013-08-01 10:50:15 -07002421if __name__ != "__main__":
2422 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002423 sys.modules[ __name__ ] = MininetCliDriver()