Merge pull request #11 from InCNTRE/master
Conformance Test-Suite 2
diff --git a/Openflow_Protocol_Messages.docx b/Openflow_Protocol_Messages.docx
new file mode 100644
index 0000000..6de88e6
--- /dev/null
+++ b/Openflow_Protocol_Messages.docx
Binary files differ
diff --git a/tests/FuncUtils.py b/tests/FuncUtils.py
new file mode 100644
index 0000000..96fc6cf
--- /dev/null
+++ b/tests/FuncUtils.py
@@ -0,0 +1,279 @@
+""" 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 testutils import *
+
+#################### 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
+ 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[2]
+ 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,stats_byte_count=0,stats_packet_count=0):
+# Verify Flow_Stats
+
+ # Send Flow_Stats_Request
+ request = message.flow_stats_request()
+ request.out_port = ofp.OFPP_NONE
+ request.table_id = 0xff
+ request.match = match
+ response, pkt = self.controller.transact(request, timeout=1)
+ self.assertTrue(response is not None, "Did not get response")
+ byte_count = 0
+ packet_count = 0
+
+ #Verify byte_count and packet_count in the reply
+ for stat in response.stats:
+ byte_count += stat.byte_count
+ packet_count += stat.packet_count
+ self.assertEqual(stats_byte_count,byte_count,
+ "Byte counter is incorrect")
+ self.assertEqual(stats_packet_count,packet_count,
+ "Packet counter is incorrect")
+
+
+############################## 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')
diff --git a/tests/Openflow_Protocol_Messages.py b/tests/Openflow_Protocol_Messages.py
new file mode 100644
index 0000000..d3db3b1
--- /dev/null
+++ b/tests/Openflow_Protocol_Messages.py
@@ -0,0 +1,385 @@
+"""These tests fall under Conformance Test-Suite (OF-SWITCH-1.0.0 TestCases).
+ Refer Documentation -- Detailed testing methodology
+ <Some of test-cases are directly taken from oftest> """
+
+"Test Suite 2 --> Openflow Protocol messages"
+
+
+import logging
+
+import unittest
+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 basic
+
+from testutils import *
+from time import sleep
+from FuncUtils import *
+
+
+of_port_map = None
+of_logger = None
+of_config = None
+
+def test_set_init(config):
+
+
+ basic.test_set_init(config)
+
+ global of_port_map
+ global of_logger
+ global of_config
+
+ of_logger = logging.getLogger("Start Openflow_Protocol_Messages Conformance Test-suite")
+ of_logger.info("Initializing test set")
+ of_port_map = config["port_map"]
+ of_config = config
+
+
+class Features_Request(basic.SimpleProtocol):
+
+ """Verify Features_Request-Reply is implemented
+ a) Send OFPT_FEATURES_REQUEST
+ b) Verify OFPT_FEATURES_REPLY is received without errors"""
+
+ def runTest(self):
+ of_logger.info("Running Features_Request test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller, of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Sending Features_Request")
+ of_logger.info("Expecting Features_Reply")
+
+ request = message.features_request()
+ rv = self.controller.message_send(request)
+ self.assertTrue(rv != -1, "Not able to send features request.")
+
+ (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_FEATURES_REPLY,
+ timeout=2)
+ self.assertTrue(response is not None,
+ 'Did not receive Features Reply')
+
+
+class Configuration_Request(basic.SimpleProtocol):
+
+ """Check basic Get Config request is implemented
+ a) Send OFPT_GET_CONFIG_REQUEST
+ b) Verify OFPT_GET_CONFIG_REPLY is received without errors"""
+
+ def runTest(self):
+
+ of_logger.info("Running Configuration_Request test ")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller, of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Sending OFPT_GET_CONFIG_REQUEST ")
+ of_logger.info("Expecting OFPT_GET_CONFIG_REPLY ")
+
+ request = message.get_config_request()
+ rv = self.controller.message_send(request)
+ self.assertTrue(rv != -1, " Not able to send get_config request.")
+
+ (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_GET_CONFIG_REPLY,
+ timeout=2)
+ self.assertTrue(response is not None,
+ 'Did not receive OFPT_GET_CONFIG_REPLY')
+
+class Modify_State_Add(basic.SimpleProtocol):
+
+ """Check basic Flow Add request is implemented
+ a) Send OFPT_FLOW_MOD , command = OFPFC_ADD
+ c) Send ofp_table_stats request , verify active_count=1 in reply"""
+
+ def runTest(self):
+
+ of_logger.info("Running Modify_State_Add test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller,of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Inserting a flow entry")
+ of_logger.info("Expecting active_count=1 in table_stats_reply")
+
+ #Insert a flow entry matching on ingress_port
+ (Pkt,match) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ # Send Table_Stats_Request and verify flow gets inserted.
+ Verify_TableStats(self,active_entries=1)
+
+
+class Modify_State_Delete(basic.SimpleProtocol):
+
+ """Check Basic Flow Delete request is implemented
+ a) Send OFPT_FLOW_MOD, command = OFPFC_ADD
+ b) Send ofp_table_stats request , verify active_count=1 in reply
+ c) Send OFPT_FLOW_MOD, command = OFPFC_DELETE
+ c) Send ofp_table_stats request , verify active_count=0 in reply"""
+
+ def runTest(self):
+
+ of_logger.info("Running Modify_State_Delete test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller,of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Inserting a flow entry and then deleting it")
+ of_logger.info("Expecting the active_count=0 in table_stats_reply")
+
+ #Insert a flow matching on ingress_port
+ (Pkt,match) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ #Verify Flow inserted.
+ Verify_TableStats(self,active_entries=1)
+
+ #Delete the flow
+ NonStrict_Delete(self,match)
+
+ # Send Table_Stats_Request and verify flow deleted.
+ Verify_TableStats(self,active_entries=0)
+
+
+
+class Modify_State_Modify(basic.SimpleDataPlane):
+
+ """Verify basic Flow Modify request is implemented
+ a) Send OFPT_FLOW_MOD, command = OFPFC_ADD, Action A
+ b) Send OFPT_FLOW_MOD, command = OFPFC_MODIFY , with output action A'
+ c) Send a packet matching the flow, verify packet implements action A' """
+
+ def runTest(self):
+
+ of_logger.info("Running Modify_State_modify test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller, of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Inserting a flow entry and then modifying it")
+ of_logger.info("Expecting the Test Packet to implement the modified action")
+
+ # Insert a flow matching on ingress_port with action A (output to of_port[1])
+ (pkt,match) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ # Modify the flow action (output to of_port[2])
+ Modify_Flow_Action(self,of_ports,match)
+
+ # Send the Test Packet and verify action implemented is A' (output to of_port[2])
+ SendPacket(self, pkt, of_ports[0],of_ports[2])
+
+
+class Read_State(basic.SimpleProtocol):
+
+ """Test that a basic Read state request (like flow_stats_get request) does not generate an error
+ a) Send OFPT_FLOW_MOD, command = OFPFC_ADD
+ b) Send ofp_flow_stats request
+ b) Verify switch replies without errors"""
+
+ def runTest(self):
+
+ of_logger.info("Running Read_State test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear switch state
+ rc = delete_all_flows(self.controller, of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Inserting a flow entry and then sending flow_stats request")
+ of_logger.info("Expecting the a flow_stats_reply without errors")
+
+ # Insert a flow with match on ingress_port
+ (pkt,match ) = Wildcard_All_Except_Ingress(self,of_ports)
+
+ #Verify Flow_Stats request does not generate errors
+ Verify_FlowStats(self,match)
+
+class Send_Packet(basic.SimpleDataPlane):
+
+ """Test packet out function
+ a) Send packet out message for each dataplane port.
+ b) Verify the packet appears on the appropriate dataplane port"""
+
+ def runTest(self):
+
+ of_logger.info("Running Send_Packet test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+
+ #Clear Switch state
+ rc = delete_all_flows(self.controller, of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ of_logger.info("Sending a packet-out for each dataplane port")
+ of_logger.info("Expecting the packet on appropriate dataplane port")
+
+ for dp_port in of_ports:
+ for outpkt, opt in [
+ (simple_tcp_packet(), "simple TCP packet"),
+ (simple_eth_packet(), "simple Ethernet packet"),
+ (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
+
+ msg = message.packet_out()
+ msg.data = str(outpkt)
+ act = action.action_output()
+ act.port = dp_port
+ self.assertTrue(msg.actions.add(act), 'Could not add action to msg')
+
+ of_logger.info("PacketOut to: " + str(dp_port))
+ rv = self.controller.message_send(msg)
+ self.assertTrue(rv == 0, "Error sending out message")
+
+ exp_pkt_arg = None
+ exp_port = None
+ if of_config["relax"]:
+ exp_pkt_arg = outpkt
+ exp_port = dp_port
+ (of_port, pkt, pkt_time) = self.dataplane.poll(timeout=2,
+ port_number=exp_port,
+ exp_pkt=exp_pkt_arg)
+
+ self.assertTrue(pkt is not None, 'Packet not received')
+ of_logger.info("PacketOut: got pkt from " + str(of_port))
+ if of_port is not None:
+ self.assertEqual(of_port, dp_port, "Unexpected receive port")
+ if not dataplane.match_exp_pkt(outpkt, pkt):
+ of_logger.debug("Sent %s" % format_packet(outpkt))
+ of_logger.debug("Resp %s" % format_packet(
+ str(pkt)[:len(str(outpkt))]))
+ self.assertEqual(str(outpkt), str(pkt)[:len(str(outpkt))],
+ 'Response packet does not match send packet')
+
+
+class Packet_In(basic.SimpleDataPlane):
+
+ """Test basic packet_in function
+ a) Send a simple tcp packet to a dataplane port, without any flow-entry
+ b) Verify that a packet_in event is sent to the controller"""
+
+ def runTest(self):
+
+ of_logger.info("Running Packet_In test")
+
+ of_ports = of_port_map.keys()
+ of_ports.sort()
+ ingress_port = of_ports[0]
+
+ #Clear Switch state
+ rc = delete_all_flows(self.controller, of_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+ self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
+
+ of_logger.info("Sending a Simple tcp packet a dataplane port")
+ of_logger.info("Expecting a packet_in event on the control plane")
+
+ # Send packet on dataplane port and verify packet_in event gets generated.
+ pkt = simple_tcp_packet()
+ self.dataplane.send(ingress_port, str(pkt))
+ of_logger.info("Sending packet to dp port " + str(ingress_port) +
+ ", expecting packet_in on control plane" )
+
+ (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_PACKET_IN,
+ timeout=2)
+ self.assertTrue(response is not None,
+ 'Packet in event is not sent to the controller')
+
+
+class Hello(basic.SimpleDataPlane):
+
+ """Test Hello messages are implemented
+ a) Create Hello messages from controller
+ b) Verify switch also exchanges hello message -- (Poll the control plane)
+ d) Verify the version field in the hello messages is openflow 1.0.0 """
+
+ def runTest(self):
+
+ of_logger.info("Running Hello test")
+
+ of_logger.info("Sending Hello")
+ of_logger.info("Expecting a Hello on the control plane with version--1.0.0")
+
+ #Send Hello message
+ request = message.hello()
+ (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_HELLO,
+ timeout=1)
+ self.assertTrue(response is not None,
+ 'Switch did not exchange hello message in return')
+ self.assertTrue(response.header.version == 0x01, 'switch openflow-version field is not 1.0.0')
+
+
+
+class EchoWithoutBody(basic.SimpleProtocol):
+
+ """Test basic echo-reply is implemented
+ a) Send echo-request from the controller side, note echo body is empty here.
+ b) Verify switch responds back with echo-reply with same xid """
+
+ def runTest(self):
+
+ of_logger.info("Running EchoWithoutBody test")
+
+ of_logger.info("Sending Echo Request")
+ of_logger.info("Expecting a Echo Reply with version--1.0.0 and same xid")
+
+ # Send echo_request
+ request = message.echo_request()
+ (response, pkt) = self.controller.transact(request)
+ self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY,'response is not echo_reply')
+ self.assertEqual(request.header.xid, response.header.xid,
+ 'response xid != request xid')
+ self.assertTrue(response.header.version == 0x01, 'switch openflow-version field is not 1.0.1')
+ self.assertEqual(len(response.data), 0, 'response data non-empty')
+
+
+class BarrierRequestReply(basic.SimpleProtocol):
+
+ """ Check basic Barrier request is implemented
+ a) Send OFPT_BARRIER_REQUEST
+ c) Verify OFPT_BARRIER_REPLY is recieved"""
+
+ def runTest(self):
+
+ of_logger.info("Running BarrierRequestReply test")
+
+ of_logger.info("Sending Barrier Request")
+ of_logger.info("Expecting a Barrier Reply with same xid")
+
+ #Send Barrier Request
+ request = message.barrier_request()
+ (response, pkt) = self.controller.transact(request)
+ self.assertEqual(response.header.type, ofp.OFPT_BARRIER_REPLY,'response is not barrier_reply')
+ self.assertEqual(request.header.xid, response.header.xid,
+ 'response xid != request xid')
+
+
+
+
+