| """ Defined Some common functions used by Conformance tests -- OF-SWITCH 1.0.0 Testcases """ |
| |
| import sys |
| import copy |
| import random |
| |
| import oftest.controller as controller |
| import oftest.cstruct as ofp |
| import oftest.message as message |
| import oftest.dataplane as dataplane |
| import oftest.action as action |
| import oftest.parse as parse |
| import logging |
| import types |
| import basic |
| from oftest.testutils import * |
| from time import sleep |
| |
| #################### Functions for various types of flow_mod ########################################################################################## |
| |
| def Exact_Match(self,of_ports,priority=0): |
| # Generate ExactMatch flow . |
| |
| #Create a simple tcp packet and generate exact flow match from it. |
| Pkt_ExactFlow = simple_tcp_packet() |
| match = parse.packet_to_flow_match(Pkt_ExactFlow) |
| self.assertTrue(match is not None, "Could not generate flow match from pkt") |
| match.in_port = of_ports[0] |
| #match.nw_src = 1 |
| match.wildcards=0 |
| msg = message.flow_mod() |
| msg.out_port = ofp.OFPP_NONE |
| msg.command = ofp.OFPFC_ADD |
| msg.buffer_id = 0xffffffff |
| msg.match = match |
| if priority != 0 : |
| msg.priority = priority |
| |
| act = action.action_output() |
| act.port = of_ports[1] |
| self.assertTrue(msg.actions.add(act), "could not add action") |
| |
| rv = self.controller.message_send(msg) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| return (Pkt_ExactFlow,match) |
| |
| |
| def Match_All_Except_Source_Address(self,of_ports,priority=0): |
| # Generate Match_All_Except_Source_Address flow |
| |
| #Create a simple tcp packet and generate match all except src address flow. |
| Pkt_WildcardSrc= simple_tcp_packet() |
| match1 = parse.packet_to_flow_match(Pkt_WildcardSrc) |
| self.assertTrue(match1 is not None, "Could not generate flow match from pkt") |
| match1.in_port = of_ports[0] |
| #match1.nw_src = 1 |
| match1.wildcards = ofp.OFPFW_DL_SRC |
| msg1 = message.flow_mod() |
| msg1.out_port = ofp.OFPP_NONE |
| msg1.command = ofp.OFPFC_ADD |
| msg1.buffer_id = 0xffffffff |
| msg1.match = match1 |
| if priority != 0 : |
| msg1.priority = priority |
| |
| act1 = action.action_output() |
| act1.port = of_ports[1] |
| self.assertTrue(msg1.actions.add(act1), "could not add action") |
| |
| rv = self.controller.message_send(msg1) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| return (Pkt_WildcardSrc,match1) |
| |
| def Wildcard_All(self,of_ports,priority=0): |
| # Generate a Wildcard_All Flow |
| |
| #Create a simple tcp packet and generate wildcard all flow match from it. |
| Pkt_Wildcard = simple_tcp_packet() |
| match2 = parse.packet_to_flow_match(Pkt_Wildcard) |
| self.assertTrue(match2 is not None, "Could not generate flow match from pkt") |
| match2.wildcards=ofp.OFPFW_ALL |
| match2.in_port = of_ports[0] |
| |
| msg2 = message.flow_mod() |
| msg2.out_port = ofp.OFPP_NONE |
| msg2.command = ofp.OFPFC_ADD |
| msg2.buffer_id = 0xffffffff |
| msg2.match = match2 |
| act2 = action.action_output() |
| act2.port = of_ports[1] |
| self.assertTrue(msg2.actions.add(act2), "could not add action") |
| if priority != 0 : |
| msg2.priority = priority |
| |
| rv = self.controller.message_send(msg2) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| return (Pkt_Wildcard,match2) |
| |
| def Wildcard_All_Except_Ingress(self,of_ports,priority=0): |
| # Generate Wildcard_All_Except_Ingress_port flow |
| |
| |
| #Create a simple tcp packet and generate wildcard all except ingress_port flow. |
| Pkt_MatchIngress = simple_tcp_packet() |
| match3 = parse.packet_to_flow_match(Pkt_MatchIngress) |
| self.assertTrue(match3 is not None, "Could not generate flow match from pkt") |
| match3.wildcards = ofp.OFPFW_ALL-ofp.OFPFW_IN_PORT |
| match3.in_port = of_ports[0] |
| |
| msg3 = message.flow_mod() |
| msg3.command = ofp.OFPFC_ADD |
| msg3.match = match3 |
| msg3.out_port = of_ports[2] # ignored by flow add,flow modify |
| msg3.cookie = random.randint(0,9007199254740992) |
| msg3.buffer_id = 0xffffffff |
| msg3.idle_timeout = 0 |
| msg3.hard_timeout = 0 |
| msg3.buffer_id = 0xffffffff |
| |
| act3 = action.action_output() |
| act3.port = of_ports[1] |
| self.assertTrue(msg3.actions.add(act3), "could not add action") |
| |
| if priority != 0 : |
| msg3.priority = priority |
| |
| rv = self.controller.message_send(msg3) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| return (Pkt_MatchIngress,match3) |
| |
| |
| def Strict_Modify_Flow_Action(self,egress_port,match,priority=0): |
| # Strict Modify the flow Action |
| |
| #Create a flow_mod message , command MODIFY_STRICT |
| msg5 = message.flow_mod() |
| msg5.match = match |
| msg5.cookie = random.randint(0,9007199254740992) |
| msg5.command = ofp.OFPFC_MODIFY_STRICT |
| msg5.buffer_id = 0xffffffff |
| act5 = action.action_output() |
| act5.port = egress_port |
| self.assertTrue(msg5.actions.add(act5), "could not add action") |
| |
| if priority != 0 : |
| msg5.priority = priority |
| |
| # Send the flow with action A' |
| rv = self.controller.message_send (msg5) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| def Modify_Flow_Action(self,of_ports,match,priority=0): |
| # Modify the flow action |
| |
| #Create a flow_mod message , command MODIFY |
| msg8 = message.flow_mod() |
| msg8.match = match |
| msg8.cookie = random.randint(0,9007199254740992) |
| msg8.command = ofp.OFPFC_MODIFY |
| #Will be ignored for flow adds and flow modify (here for test-case Add_Modify_With_Outport) |
| msg8.out_port = of_ports[3] |
| msg8.buffer_id = 0xffffffff |
| act8 = action.action_output() |
| act8.port = of_ports[2] |
| self.assertTrue(msg8.actions.add(act8), "could not add action") |
| |
| if priority != 0 : |
| msg8.priority = priority |
| |
| # Send the flow with action A' |
| rv = self.controller.message_send (msg8) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| |
| ########################### Verify Stats Functions ########################################################################################### |
| |
| def Verify_TableStats(self,active_entries=0,): |
| #Verify Table_Stats |
| |
| #Send Table_Stats_Request |
| request = message.table_stats_request() |
| response, pkt = self.controller.transact(request, timeout=1) |
| self.assertTrue(response is not None, "Did not get response") |
| active_count=0 |
| |
| #Verify active_count in the reply |
| for stat in response.stats: |
| active_count += stat.active_count |
| self.assertTrue(active_entries == active_count,"Incorrect no. of flows in Table") |
| |
| |
| def Verify_FlowStats(self,match,byte_count=0,packet_count=0): |
| # Verify flow counters : byte_count and packet_count |
| |
| stat_req = message.flow_stats_request() |
| stat_req.match = match |
| stat_req.table_id = 0xff |
| stat_req.out_port = ofp.OFPP_NONE |
| test_timeout = 10 |
| all_packets_received = 0 |
| for i in range(0,test_timeout): |
| |
| response, pkt = self.controller.transact(stat_req, |
| timeout=test_timeout) |
| self.assertTrue(response is not None, |
| "No response to stats request") |
| for obj in response.stats: |
| if ( obj.packet_count == packet_count and obj.byte_count == byte_count ) : |
| all_packets_received = 1 |
| |
| if all_packets_received: |
| break |
| sleep(1) |
| |
| self.assertTrue(all_packets_received, |
| "Flow counters are incorrect") |
| |
| def Verify_PortStats(self,in_port,rx_dropped): |
| #Verify Port counters like rx_dropped |
| |
| port_stats_req = message.port_stats_request() |
| port_stats_req.port_no = in_port |
| resp,pkt = self.controller.transact(port_stats_req) |
| self.assertTrue(resp is not None,"No response received for port stats request") |
| self.assertTrue(resp.rx_dropped == rx_dropped, "Packets not dropped") |
| |
| |
| |
| ############################## Various delete commands ############################################################################################# |
| |
| def Strict_Delete(self,match,priority=0): |
| # Issue Strict Delete |
| |
| #Create flow_mod message, command DELETE_STRICT |
| msg4 = message.flow_mod() |
| msg4.out_port = ofp.OFPP_NONE |
| msg4.command = ofp.OFPFC_DELETE_STRICT |
| msg4.buffer_id = 0xffffffff |
| msg4.match = match |
| |
| if priority != 0 : |
| msg4.priority = priority |
| |
| rv = self.controller.message_send(msg4) |
| self.assertTrue(rv!= -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller), 0, "Barrier failed") |
| |
| |
| |
| def NonStrict_Delete(self,match,priority=0): |
| # Issue Non_Strict Delete |
| |
| #Create flow_mod message, command DELETE |
| msg6 = message.flow_mod() |
| msg6.out_port = ofp.OFPP_NONE |
| msg6.command = ofp.OFPFC_DELETE |
| msg6.buffer_id = 0xffffffff |
| msg6.match = match |
| |
| if priority != 0 : |
| msg6.priority = priority |
| |
| rv = self.controller.message_send(msg6) |
| self.assertTrue(rv != -1, "Error installing flow mod") |
| self.assertEqual(do_barrier(self.controller),0, "Barrier failed") |
| |
| |
| ########################################################################################################################################################### |
| |
| def SendPacket(obj, pkt, ingress_port, egress_port): |
| #Send Packets on a specified ingress_port and verify if its recieved on correct egress_port. |
| |
| obj.dataplane.send(ingress_port, str(pkt)) |
| exp_pkt_arg = pkt |
| exp_port = egress_port |
| |
| (rcv_port, rcv_pkt, pkt_time) = obj.dataplane.poll(timeout=2, |
| port_number=exp_port, |
| exp_pkt=exp_pkt_arg) |
| obj.assertTrue(rcv_pkt is not None, |
| "Packet not received on port " + str(egress_port)) |
| obj.assertEqual(rcv_port, egress_port, |
| "Packet received on port " + str(rcv_port) + |
| ", expected port " + str(egress_port)) |
| obj.assertEqual(str(pkt), str(rcv_pkt), |
| 'Response packet does not match send packet') |
| |
| |
| def sw_supported_actions(parent,use_cache=False): |
| #Returns the switch's supported actions |
| |
| cache_supported_actions = None |
| if cache_supported_actions is None or not use_cache: |
| request = message.features_request() |
| (reply, pkt) = parent.controller.transact(request) |
| parent.assertTrue(reply is not None, "Did not get response to ftr req") |
| cache_supported_actions = reply.actions |
| return cache_supported_actions |
| |