blob: 9cf13ed0cac11346d083179cf3a3c390d77c6dbb [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 26-Oct-2012
4
5@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
6
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20
21
22MininetCliDriver is the basic driver which will handle the Mininet functions
23'''
admin2a9548d2014-06-17 14:08:07 -070024import traceback
adminbae64d82013-08-01 10:50:15 -070025import pexpect
26import struct
27import fcntl
28import os
29import signal
30import re
31import sys
32import core.teston
33sys.path.append("../")
34from drivers.common.cli.emulatordriver import Emulator
35from drivers.common.clidriver import CLI
36from time import time
37
38class RemoteMininetDriver(Emulator):
39 '''
adminaeedddd2013-08-02 15:14:15 -070040 RemoteMininetCliDriver is the basic driver which will handle the Mininet functions
41 The main different between this and the MininetCliDriver is that this one does not build the mininet.
42 It assumes that there is already a mininet running on the target.
adminbae64d82013-08-01 10:50:15 -070043 '''
44 def __init__(self):
45 super(Emulator, self).__init__()
46 self.handle = self
47 self.wrapped = sys.modules[__name__]
48 self.flag = 0
49
50 def connect(self, **connectargs):
51 #,user_name, ip_address, pwd,options):
52 # Here the main is the TestON instance after creating all the log handles.
53 for key in connectargs:
54 vars(self)[key] = connectargs[key]
55
56 self.name = self.options['name']
57 self.handle = super(RemoteMininetDriver, self).connect(user_name = self.user_name, ip_address = self.ip_address,port = None, pwd = self.pwd)
58
59 self.ssh_handle = self.handle
60
61 # Copying the readme file to process the
62 if self.handle :
63 return main.TRUE
64
65 else :
66 main.log.error("Connection failed to the host "+self.user_name+"@"+self.ip_address)
67 main.log.error("Failed to connect to the Mininet")
68 return main.FALSE
admin98ad0092014-07-23 16:51:07 -070069
70#*********************************************************************************************
71#*********************************************************************************************
72# checkForLoss will determine if any of the pings had any packets lost during the course of
73# the pingLong.
74#*********************************************************************************************
75#*********************************************************************************************
76
admin2580a0e2014-07-29 11:24:34 -070077 def checkForLoss(self, pingList):
Jon Hall6c794f32014-08-14 13:33:13 -070078 '''
79 Returns main.FALSE for 0% packet loss and
80 Returns main.ERROR if "found multiple mininet" is found and
81 Returns main.TRUE else
82 '''
Jon Hall368769f2014-11-19 15:43:35 -080083 #TODO: maybe we want to return the % loss instead? This way we can set an acceptible loss %.
84 #EX: 393 packets transmitted, 380 received, 3% packet loss, time 78519ms
85 # we may need to return a float to get around rounding errors
86
admin98ad0092014-07-23 16:51:07 -070087 import os
admin2580a0e2014-07-29 11:24:34 -070088 self.handle.sendline("")
89 self.handle.expect("\$")
Jon Hall368769f2014-11-19 15:43:35 -080090 #Clear any output waiting in the bg from killing pings
91 self.handle.sendline("")
92 self.handle.expect("\$")
admin2580a0e2014-07-29 11:24:34 -070093 self.handle.sendline("cat " + pingList)
94 self.handle.expect(pingList)
95 self.handle.expect("\$")
96 outputs = self.handle.before + self.handle.after
97 if re.search(" 0% packet loss",outputs):
admin98ad0092014-07-23 16:51:07 -070098 return main.FALSE
admin2580a0e2014-07-29 11:24:34 -070099 elif re.search("found multiple mininet",outputs):
100 return main.ERROR
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700101 else:
102 print outputs
103 return main.TRUE
104
admin98ad0092014-07-23 16:51:07 -0700105
106
adminbae64d82013-08-01 10:50:15 -0700107 def pingLong(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700108 '''
109 Starts a continuous ping on the mininet host outputing to a file in the /tmp dir.
110 '''
Jon Hall6c794f32014-08-14 13:33:13 -0700111 self.handle.sendline("")
112 self.handle.expect("\$")
admin98ad0092014-07-23 16:51:07 -0700113 args = utilities.parse_args(["SRC","TARGET","PINGTIME"],**pingParams)
Jon Hall6c794f32014-08-14 13:33:13 -0700114 precmd = "sudo rm /tmp/ping." + args["SRC"]
admin530b4c92013-08-14 16:54:35 -0700115 self.execute(cmd=precmd,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700116 command = "sudo mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -i .2 -w " + str(args['PINGTIME']) + " > /tmp/ping." + args["SRC"] + " &"
adminbae64d82013-08-01 10:50:15 -0700117 main.log.info( command )
118 self.execute(cmd=command,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700119 self.handle.sendline("")
120 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700121 return main.TRUE
122
123 def pingstatus(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700124 '''
125 Tails the respective ping output file and check that there is a moving "64 bytes"
126 '''
Jon Hall6c794f32014-08-14 13:33:13 -0700127 self.handle.sendline("")
128 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700129 args = utilities.parse_args(["SRC"],**pingParams)
130 self.handle.sendline("tail /tmp/ping." + args["SRC"])
131 self.handle.expect("tail")
132 self.handle.expect("\$")
133 result = self.handle.before + self.handle.after
Jon Hall6c794f32014-08-14 13:33:13 -0700134 self.handle.sendline("")
135 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700136 if re.search('Unreachable', result ):
137 main.log.info("Unreachable found in ping logs...")
138 return main.FALSE
139 elif re.search('64\sbytes', result):
140 main.log.info("Pings look good")
141 return main.TRUE
142 else:
143 main.log.info("No, or faulty ping data...")
144 return main.FALSE
145
Jon Hall6c794f32014-08-14 13:33:13 -0700146 def pingKill(self, testONUser, testONIP):
adminaeedddd2013-08-02 15:14:15 -0700147 '''
148 Kills all continuous ping processes.
149 Then copies all the ping files to the TestStation.
150 '''
151 import time
Jon Hall6c794f32014-08-14 13:33:13 -0700152 self.handle.sendline("")
153 self.handle.expect("\$")
admin2580a0e2014-07-29 11:24:34 -0700154 command = "sudo kill -SIGINT `pgrep ping`"
adminbae64d82013-08-01 10:50:15 -0700155 main.log.info( command )
156 self.execute(cmd=command,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700157 #Commenting out in case TestON and MN are on the same machine. scp overrights the file anyways
158 #main.log.info( "Removing old ping data" )
159 #command = "rm /tmp/ping.*"
160 #os.popen(command)
161 #time.sleep(2)
adminbae64d82013-08-01 10:50:15 -0700162 main.log.info( "Transferring ping files to TestStation" )
Jon Hall6c794f32014-08-14 13:33:13 -0700163 command = "scp /tmp/ping.* "+ str(testONUser) + "@" + str(testONIP) + ":/tmp/"
adminbae64d82013-08-01 10:50:15 -0700164 self.execute(cmd=command,prompt="100%",timeout=20)
Jon Hall6c794f32014-08-14 13:33:13 -0700165 self.handle.sendline("")
Jon Hall368769f2014-11-19 15:43:35 -0800166 i=self.handle.expect(["password","\$"])
167 if i == 0:
168 main.log.error("Error, sudo asking for password")
169 main.log.error(self.handle.before)
170 return main.FALSE
171 else:
172 return main.TRUE
admin2580a0e2014-07-29 11:24:34 -0700173
174 def pingLongKill(self):
175 import time
Jon Hall6c794f32014-08-14 13:33:13 -0700176 self.handle.sendline("")
177 self.handle.expect("\$")
admin2580a0e2014-07-29 11:24:34 -0700178 command = "sudo kill -SIGING `pgrep ping`"
179 main.log.info(command)
180 self.execute(cmd=command,prompt="(.*)",timeout=10)
Jon Hall6c794f32014-08-14 13:33:13 -0700181 self.handle.sendline("")
182 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700183 return main.TRUE
shahshreya28bb18e2014-11-17 10:26:23 -0800184
185 def pingHostOptical(self,**pingParams):
186 '''
187 This function is only for Packey Optical related ping
188 Use the next pingHost() function for all normal scenarios)
189 Ping from one mininet host to another
190 Currently the only supported Params: SRC and TARGET
191 '''
192 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
193 #command = args["SRC"] + " ping -" + args["CONTROLLER"] + " " +args ["TARGET"]
194 command = args["SRC"] + " ping "+args ["TARGET"]+" -c 1 -i 1 -W 8"
195 try:
196 main.log.warn("Sending: " + command)
197 #response = self.execute(cmd=command,prompt="mininet",timeout=10 )
198 self.handle.sendline(command)
199 i = self.handle.expect([command,pexpect.TIMEOUT])
200 if i == 1:
201 main.log.error(self.name + ": timeout when waiting for response from mininet")
202 main.log.error("response: " + str(self.handle.before))
203 i = self.handle.expect(["mininet>",pexpect.TIMEOUT])
204 if i == 1:
205 main.log.error(self.name + ": timeout when waiting for response from mininet")
206 main.log.error("response: " + str(self.handle.before))
207 response = self.handle.before
208 except pexpect.EOF:
209 main.log.error(self.name + ": EOF exception found")
210 main.log.error(self.name + ": " + self.handle.before)
211 main.cleanup()
212 main.exit()
213 main.log.info(self.name+": Ping Response: "+ response )
214 #if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
215 if re.search(',\s0\%\spacket\sloss',response):
216 main.log.info(self.name+": no packets lost, host is reachable")
217 main.last_result = main.TRUE
218 return main.TRUE
219 else :
220 main.log.error(self.name+": PACKET LOST, HOST IS NOT REACHABLE")
221 main.last_result = main.FALSE
222 return main.FALSE
223
adminbae64d82013-08-01 10:50:15 -0700224 def pingHost(self,**pingParams):
adminaeedddd2013-08-02 15:14:15 -0700225 '''
226 Pings between two hosts on remote mininet
227 '''
Jon Hall6c794f32014-08-14 13:33:13 -0700228 self.handle.sendline("")
229 self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700230 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
shahshreya28bb18e2014-11-17 10:26:23 -0800231 #command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -c 4 -W 1 -i .2"
adminbae64d82013-08-01 10:50:15 -0700232 command = "mininet/util/m " + args["SRC"] + " ping "+args ["TARGET"]+" -c 4 -W 1 -i .2"
233 main.log.info ( command )
234 response = self.execute(cmd=command,prompt="rtt",timeout=10 )
shahshreya28bb18e2014-11-17 10:26:23 -0800235 #self.handle.sendline("")
236 #self.handle.expect("\$")
adminbae64d82013-08-01 10:50:15 -0700237 if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
238 main.log.info("NO PACKET LOSS, HOST IS REACHABLE")
239 main.last_result = main.TRUE
240 return main.TRUE
241 else :
242 main.log.error("PACKET LOST, HOST IS NOT REACHABLE")
243 main.last_result = main.FALSE
244 return main.FALSE
245
246
247 def checknum(self,num):
248 '''
adminaeedddd2013-08-02 15:14:15 -0700249 Verifies the correct number of switches are running
adminbae64d82013-08-01 10:50:15 -0700250 '''
251 if self.handle :
252 self.handle.sendline("")
253 self.handle.expect("\$")
254 self.handle.sendline('ifconfig -a | grep "sw.. " | wc -l')
255 self.handle.expect("wc")
256 self.handle.expect("\$")
257 response = self.handle.before
258 self.handle.sendline('ps -ef | grep "bash -ms mininet:sw" | grep -v color | wc -l')
259 self.handle.expect("color")
260 self.handle.expect("\$")
261 response2 = self.handle.before
262
263 if re.search(num, response):
264 if re.search(num, response2):
265 return main.TRUE
266 else:
267 return main.FALSE
268 else:
269 return main.FALSE
270 else :
271 main.log.error("Connection failed to the host")
272
admin2a9548d2014-06-17 14:08:07 -0700273 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633"):
274 '''
275 Runs tpdump on an intferface and saves the file
276 intf can be specified, or the default eth0 is used
277 '''
278 try:
279 self.handle.sendline("")
280 self.handle.sendline("sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
281 self.handle.sendline("")
282 self.handle.sendline("")
283 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"\$"],timeout=10)
284 main.log.warn(self.handle.before + self.handle.after)
285 if i == 0:
286 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
287 return main.FALSE
288 elif i == 1:
289 main.log.info(self.name + ": tcpdump started on " + intf)
290 return main.TRUE
291 elif i == 2:
292 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
293 return main.FALSE
294 elif i ==3:
295 main.log.info(self.name +": " + self.handle.before)
296 return main.TRUE
297 else:
298 main.log.error(self.name + ": tcpdump - unexpected response")
299 return main.FALSE
300 except pexpect.EOF:
301 main.log.error(self.name + ": EOF exception found")
302 main.log.error(self.name + ": " + self.handle.before)
303 main.cleanup()
304 main.exit()
305 except:
306 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
307 main.log.error( traceback.print_exc() )
308 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
309 main.cleanup()
310 main.exit()
311
312 def stop_tcpdump(self):
313 "pkills tcpdump"
314 try:
315 self.handle.sendline("sudo pkill tcpdump")
316 self.handle.sendline("")
317 self.handle.sendline("")
318 self.handle.expect("\$")
319 except pexpect.EOF:
320 main.log.error(self.name + ": EOF exception found")
321 main.log.error(self.name + ": " + self.handle.before)
322 main.cleanup()
323 main.exit()
324 except:
325 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
326 main.log.error( traceback.print_exc() )
327 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
328 main.cleanup()
329 main.exit()
330
shahshreya4d79aab2014-11-07 15:20:41 -0800331 def run_optical_mn_script(self):
shahshreya28bb18e2014-11-17 10:26:23 -0800332 '''
333 This function is only meant for Packet Optical.
334 It runs the python script "optical.py" to create the packet layer(mn)
335 topology
336 '''
337 try:
338 self.handle.sendline("")
339 self.handle.expect("\$")
340 self.handle.sendline("cd ~")
341 self.handle.expect("\$")
342 self.handle.sendline("sudo python optical.py")
343 self.handle.expect(">")
344 return main.TRUE
345 except pexpect.EOF:
346 main.log.error(self.name + ": EOF exception found")
347 main.log.error(self.name + ": " + self.handle.before)
348 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700349
350 def disconnect(self):
adminaeedddd2013-08-02 15:14:15 -0700351 '''
352 Called at the end of the test to disconnect the handle.
353 '''
adminbae64d82013-08-01 10:50:15 -0700354 response = ''
355 #print "Disconnecting Mininet"
356 if self.handle:
357 self.handle.sendline("exit")
358 self.handle.expect("exit")
359 self.handle.expect("(.*)")
360 response = self.handle.before
361
362 else :
363 main.log.error("Connection failed to the host")
364 response = main.FALSE
365 return response
366
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700367 def get_flowTable(self, protoVersion, sw):
santhosh9da93892014-07-28 14:11:19 -0700368 self.handle.sendline("cd")
Jon Hall368769f2014-11-19 15:43:35 -0800369 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
Jon Hall6c794f32014-08-14 13:33:13 -0700370 #TODO: Write seperate versions of the function for this, possibly a string that tells it which switch is in use?
371 #For 1.0 version of OVS
372 #command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $6 $7 }' |sort -n -k1"
373 #for 1.3 version of OVS
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700374 #command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $3 $7 $8}' |sort -n -k1"
375 #NOTE: Use format to force consistent flow table output across versions
376 if protoVersion==1.0:
377 command = "sudo ovs-ofctl dump-flows " + sw + " -F OpenFlow10-table_id | awk '{OFS=\",\" ; print $1 $3 $6 $7 $8}' |sort -n -k1"
378 self.handle.sendline(command)
379 self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
380 self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
381 response = self.handle.before
382 #print "response=", response
383 return response
384 elif protoVersion==1.3:
385 command = "sudo ovs-ofctl dump-flows " + sw + " -O OpenFlow13 | awk '{OFS=\",\" ; print $1 $3 $6 $7}' |sort -n -k1"
386 self.handle.sendline(command)
387 #print "ovs-vsctl Command sent status."
388 #self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
389 #print "sort return status: "
390 #print self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
391 #print self.handle.before
392 self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
393 #print "OFPST_FLOW expected status: "
394 #print self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
395 #print self.handle.before
396 response = self.handle.before
397 #print "response=", response
398 return response
santhosh19fd8032014-07-29 11:56:17 -0700399
400
401 def flow_comp(self,flow1,flow2):
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700402 #print "Inside flow compare function"
403 #print "Flow1 Table:"
404 #for flow in flow1:
405 #print flow1
406 #print "Flow2 Table"
407 #for flow in flow2:
408 #print flow2
409
santhosh19fd8032014-07-29 11:56:17 -0700410 if flow1==flow2:
411 return main.TRUE
412 else:
Jon Hall6c794f32014-08-14 13:33:13 -0700413 main.log.info("Flow tables do not match, printing tables:")
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700414 #main.log.info("Flow Table 1:")
415 #main.log.info(flow1)
416 #main.log.info("Flow Table 2:")
417 #main.log.info(flow2)
santhosh19fd8032014-07-29 11:56:17 -0700418 return main.FALSE
419
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700420 def setIpTablesOUTPUT(self, dst_ip, dst_port, action='add', packet_type='tcp',rule='DROP'):
421 '''
422 Description:
423 add or remove iptables rule to DROP (default) packets from specific IP and PORT
424 Usage:
425 * specify action ('add' or 'remove')
426 when removing, pass in the same argument as you would add. It will
427 delete that specific rule.
428 * specify the destination ip to block with dst_ip
429 * specify destination port to block to dst_port
430 * optional packet type to block (default tcp)
431 * optional iptables rule (default DROP)
432 WARNING:
433 * This function uses root privilege iptables command which may result in
434 unwanted network errors. USE WITH CAUTION
435 '''
436 import re
437 import time
438
439 #NOTE*********
440 # The strict checking methods of this driver function is intentional
441 # to discourage any misuse or error of iptables, which can cause
442 # severe network errors
443 #*************
444
445 #NOTE: Sleep needed to give some time for rule to be added and registered
446 # to the instance
447 time.sleep(5)
448
449 action_type = action.lower()
450 if action_type != 'add' and action_type !='remove':
451 main.log.error("Invalid action type. 'add' or 'remove' table rule")
452 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
453 #NOTE: Currently only supports rules DROP, ACCEPT, and LOG
454 main.log.error("Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only.")
455 return
456 return
457 else:
458
459 #If there is no existing rule in the iptables, we will see an
460 #'iptables:'... message. We expect to see this message.
461 #Otherwise, if there IS an existing rule, we will get the prompt
462 # back, hence why we expect $ for remove type. We want to remove
463 # an already existing rule
464
465 if action_type == 'add':
466 #NOTE: "iptables:" expect is a result of return from the command
467 # iptables -C ...
468 # Any changes by the iptables command return string
469 # will result in failure of the function. (deemed unlikely
470 # at the time of writing this function)
471 #Check for existing rules on current input
472 self.handle.sendline("")
473 self.handle.expect("\$")
474 self.handle.sendline("sudo iptables -C OUTPUT -p "+str(packet_type)+
475 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
476 i = self.handle.expect(["iptables:", "\$"])
477 print i
478 print self.handle.before
479 print "after: "
480 print self.handle.after
481
482 elif action_type == 'remove':
483 #Check for existing rules on current input
484 self.handle.sendline("")
485 self.handle.expect("\$")
486 self.handle.sendline("sudo iptables -C OUTPUT -p "+str(packet_type)+
487 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
488 self.handle.expect("\$")
489 print "before: "
490 print self.handle.before
491 actual_string = self.handle.after
492 expect_string = "iptables:"
493 print "Actual String:"
494 print actual_string
495
496 if re.search(expect_string, actual_string):
497 match_result = main.TRUE
498 else:
499 match_result = main.FALSE
500 #If match_result is main.TRUE, it means there is no matching rule.
501
502 #If tables does not exist and expected prompt is returned, go ahead and
503 #add iptables rule
504 if match_result == main.TRUE:
505 #Ensure action type is add
506 if action_type == 'add':
507 #-A is the 'append' action of iptables
508 action_add = '-A'
509 try:
510 self.handle.sendline("")
511 self.handle.sendline("sudo iptables "+action_add+" OUTPUT -p "+str(packet_type)+
512 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
513
514 info_string = "Rules added to "+str(self.name)
515 info_string += "iptable rule added to block IP: "+str(dst_ip)
516 info_string += "Port: "+str(dst_port)+" Rule: "+str(rule)
517
518 main.log.info(info_string)
519
520 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
521 except pexpect.TIMEOUT:
522 main.log.error(self.name + ": Timeout exception in setIpTables function")
523 except:
524 main.log.error( traceback.print_exc())
525 main.cleanup()
526 main.exit()
527 else:
528 main.log.error("Given rule already exists, but attempted to add it")
529 #If match_result is 0, it means there IS a matching rule provided
530 elif match_result == main.FALSE:
531 #Ensure action type is remove
532 if action_type == 'remove':
533 #-D is the 'delete' rule of iptables
534 action_remove = '-D'
535 try:
536 self.handle.sendline("")
537 #Delete a specific rule specified into the function
538 self.handle.sendline("sudo iptables "+action_remove+" OUTPUT -p "+str(packet_type)+
539 " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
540
541 info_string = "Rules removed from "+str(self.name)
542 info_string += " iptables rule removed from blocking IP: "+str(dst_ip)
543 info_string += " Port: "+str(dst_port)+" Rule: "+str(rule)
544
545 main.log.info(info_string)
546
547 self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
548 except pexpect.TIMEOUT:
549 main.log.error(self.name + ": Timeout exception in setIpTables function")
550 except:
551 main.log.error( traceback.print_exc())
552 main.cleanup()
553 main.exit()
554 else:
555 main.log.error("Given rule does not exist, but attempted to remove it")
556 else:
557 #NOTE: If a bad usage of this function occurs, exit the entire test
558 main.log.error("Bad rule given for iptables. Exiting...")
559 main.cleanup()
560 main.exit()
561
562
adminbae64d82013-08-01 10:50:15 -0700563if __name__ != "__main__":
564 import sys
565 sys.modules[__name__] = RemoteMininetDriver()