Added arg3 to take care of 1.3 switches
diff --git a/TestON/drivers/common/cli/emulator/remotemininetdriver.py b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
index d6e839d..2acddb4 100644
--- a/TestON/drivers/common/cli/emulator/remotemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
@@ -91,7 +91,10 @@
return main.FALSE
elif re.search("found multiple mininet",outputs):
return main.ERROR
- return main.TRUE
+ else:
+ print outputs
+ return main.TRUE
+
def pingLong(self,**pingParams):
@@ -421,6 +424,7 @@
return main.TRUE
def add_switch(self,sw):
+ #FIXME: Remove hardcoded number of ports
self.handle.sendline("")
self.handle.expect("\$")
self.handle.sendline("sudo ovs-vsctl add-br "+sw)
@@ -472,32 +476,204 @@
response = main.FALSE
return response
- def get_flowTable(self,sw):
+ def get_flowTable(self, protoVersion, sw):
self.handle.sendline("cd")
- self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
+ #self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
+ print "cd expect status: "
+ print self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
#TODO: Write seperate versions of the function for this, possibly a string that tells it which switch is in use?
#For 1.0 version of OVS
#command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $6 $7 }' |sort -n -k1"
#for 1.3 version of OVS
- command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $3 $7 $8}' |sort -n -k1"
- self.handle.sendline(command)
- self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
- self.handle.expect(["NXST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
- response = self.handle.before
- return response
+ #command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $3 $7 $8}' |sort -n -k1"
+ #NOTE: Use format to force consistent flow table output across versions
+ if protoVersion==1.0:
+ command = "sudo ovs-ofctl dump-flows " + sw + " -F OpenFlow10-table_id | awk '{OFS=\",\" ; print $1 $3 $6 $7 $8}' |sort -n -k1"
+ self.handle.sendline(command)
+ self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
+ self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
+ response = self.handle.before
+ #print "response=", response
+ return response
+ elif protoVersion==1.3:
+ command = "sudo ovs-ofctl dump-flows " + sw + " -O OpenFlow13 | awk '{OFS=\",\" ; print $1 $3 $6 $7}' |sort -n -k1"
+ self.handle.sendline(command)
+ #print "ovs-vsctl Command sent status."
+ #self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
+ #print "sort return status: "
+ #print self.handle.expect(["sort -n -k1",pexpect.EOF,pexpect.TIMEOUT])
+ #print self.handle.before
+ self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
+ #print "OFPST_FLOW expected status: "
+ #print self.handle.expect(["OFPST_FLOW",pexpect.EOF,pexpect.TIMEOUT])
+ #print self.handle.before
+ response = self.handle.before
+ #print "response=", response
+ return response
def flow_comp(self,flow1,flow2):
+ #print "Inside flow compare function"
+ #print "Flow1 Table:"
+ #for flow in flow1:
+ #print flow1
+ #print "Flow2 Table"
+ #for flow in flow2:
+ #print flow2
+
if flow1==flow2:
return main.TRUE
else:
main.log.info("Flow tables do not match, printing tables:")
- main.log.info("Flow Table 1:")
- main.log.info(flow1)
- main.log.info("Flow Table 2:")
- main.log.info(flow2)
+ #main.log.info("Flow Table 1:")
+ #main.log.info(flow1)
+ #main.log.info("Flow Table 2:")
+ #main.log.info(flow2)
return main.FALSE
+ def setIpTablesOUTPUT(self, dst_ip, dst_port, action='add', packet_type='tcp',rule='DROP'):
+ '''
+ Description:
+ add or remove iptables rule to DROP (default) packets from specific IP and PORT
+ Usage:
+ * specify action ('add' or 'remove')
+ when removing, pass in the same argument as you would add. It will
+ delete that specific rule.
+ * specify the destination ip to block with dst_ip
+ * specify destination port to block to dst_port
+ * optional packet type to block (default tcp)
+ * optional iptables rule (default DROP)
+ WARNING:
+ * This function uses root privilege iptables command which may result in
+ unwanted network errors. USE WITH CAUTION
+ '''
+ import re
+ import time
+
+ #NOTE*********
+ # The strict checking methods of this driver function is intentional
+ # to discourage any misuse or error of iptables, which can cause
+ # severe network errors
+ #*************
+
+ #NOTE: Sleep needed to give some time for rule to be added and registered
+ # to the instance
+ time.sleep(5)
+
+ action_type = action.lower()
+ if action_type != 'add' and action_type !='remove':
+ main.log.error("Invalid action type. 'add' or 'remove' table rule")
+ if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
+ #NOTE: Currently only supports rules DROP, ACCEPT, and LOG
+ main.log.error("Invalid rule. 'DROP' or 'ACCEPT' or 'LOG' only.")
+ return
+ return
+ else:
+
+ #If there is no existing rule in the iptables, we will see an
+ #'iptables:'... message. We expect to see this message.
+ #Otherwise, if there IS an existing rule, we will get the prompt
+ # back, hence why we expect $ for remove type. We want to remove
+ # an already existing rule
+
+ if action_type == 'add':
+ #NOTE: "iptables:" expect is a result of return from the command
+ # iptables -C ...
+ # Any changes by the iptables command return string
+ # will result in failure of the function. (deemed unlikely
+ # at the time of writing this function)
+ #Check for existing rules on current input
+ self.handle.sendline("")
+ self.handle.expect("\$")
+ self.handle.sendline("sudo iptables -C OUTPUT -p "+str(packet_type)+
+ " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
+ i = self.handle.expect(["iptables:", "\$"])
+ print i
+ print self.handle.before
+ print "after: "
+ print self.handle.after
+
+ elif action_type == 'remove':
+ #Check for existing rules on current input
+ self.handle.sendline("")
+ self.handle.expect("\$")
+ self.handle.sendline("sudo iptables -C OUTPUT -p "+str(packet_type)+
+ " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
+ self.handle.expect("\$")
+ print "before: "
+ print self.handle.before
+ actual_string = self.handle.after
+ expect_string = "iptables:"
+ print "Actual String:"
+ print actual_string
+
+ if re.search(expect_string, actual_string):
+ match_result = main.TRUE
+ else:
+ match_result = main.FALSE
+ #If match_result is main.TRUE, it means there is no matching rule.
+
+ #If tables does not exist and expected prompt is returned, go ahead and
+ #add iptables rule
+ if match_result == main.TRUE:
+ #Ensure action type is add
+ if action_type == 'add':
+ #-A is the 'append' action of iptables
+ action_add = '-A'
+ try:
+ self.handle.sendline("")
+ self.handle.sendline("sudo iptables "+action_add+" OUTPUT -p "+str(packet_type)+
+ " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
+
+ info_string = "Rules added to "+str(self.name)
+ info_string += "iptable rule added to block IP: "+str(dst_ip)
+ info_string += "Port: "+str(dst_port)+" Rule: "+str(rule)
+
+ main.log.info(info_string)
+
+ self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
+ except pexpect.TIMEOUT:
+ main.log.error(self.name + ": Timeout exception in setIpTables function")
+ except:
+ main.log.error( traceback.print_exc())
+ main.cleanup()
+ main.exit()
+ else:
+ main.log.error("Given rule already exists, but attempted to add it")
+ #If match_result is 0, it means there IS a matching rule provided
+ elif match_result == main.FALSE:
+ #Ensure action type is remove
+ if action_type == 'remove':
+ #-D is the 'delete' rule of iptables
+ action_remove = '-D'
+ try:
+ self.handle.sendline("")
+ #Delete a specific rule specified into the function
+ self.handle.sendline("sudo iptables "+action_remove+" OUTPUT -p "+str(packet_type)+
+ " -d "+ str(dst_ip)+" --dport "+str(dst_port)+" -j "+str(rule))
+
+ info_string = "Rules removed from "+str(self.name)
+ info_string += " iptables rule removed from blocking IP: "+str(dst_ip)
+ info_string += " Port: "+str(dst_port)+" Rule: "+str(rule)
+
+ main.log.info(info_string)
+
+ self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
+ except pexpect.TIMEOUT:
+ main.log.error(self.name + ": Timeout exception in setIpTables function")
+ except:
+ main.log.error( traceback.print_exc())
+ main.cleanup()
+ main.exit()
+ else:
+ main.log.error("Given rule does not exist, but attempted to remove it")
+ else:
+ #NOTE: If a bad usage of this function occurs, exit the entire test
+ main.log.error("Bad rule given for iptables. Exiting...")
+ main.cleanup()
+ main.exit()
+
+
if __name__ != "__main__":
import sys
sys.modules[__name__] = RemoteMininetDriver()