Merge remote-tracking branch 'main/counters'
diff --git a/Detailed_Testing_Methodology.txt b/Detailed_Testing_Methodology.txt
index 7b3c0b2..eda3daa 100644
--- a/Detailed_Testing_Methodology.txt
+++ b/Detailed_Testing_Methodology.txt
@@ -1434,4 +1434,389 @@
a) Send queue_stats request for port=egress_port and queue_ids=ofp.OFPQ_ALL
B) send queue_stats request for egress_port and queue_id[0] (i.e first queue configured for egress_port)
c) Verify reply has tx_errors count .
-d) Repear b , c for the all queue_ids of egress_port
\ No newline at end of file
+d) Repear b , c for the all queue_ids of egress_port
+
+
+
+
+
+**** Flow matches ****
+
+
+
+1. All Wildcard Match
+
+Test Description: Adding a Flow that matches all the possible fields
+
+Test mode: Automated
+Test Tile: AllWildcardMatch
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with wildcard = OFPFW_ALL (wildcard all fields), action output to egress_port
+b) Send packets with different header fields
+c) Verify all packets match the flow and implement the action specified.
+
+
+2. Single Header Field: Ingress Port
+
+Test Description: Match on Ingress Port and Wildcard rest
+
+Test mode: Automated
+Test Tile: IngressPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = in_port (say port x), action output to egress_port
+b) Send packet on port x
+c) Verify packet was recieved on egress_port
+d) Send packet on port y
+e) Verify PacketIn event was triggered on control plane
+
+
+
+3. Single Header Field: Ethernet Src Address
+
+Test Description: Match on Ethernet Source Address and Wildcard rest
+
+Test mode: Automated
+Test Tile: EthernetSrcAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = dl_src (say x) , action output to egress_port
+b) Send packet wth dl_src = x
+c) Verify packet was recieved on egress_port
+d) Send packet with dl_src = y
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+4. Single Header Field: Ethernet Dst Address
+
+Test Description: Match on Ethernet Destination Address and Wildcard rest
+
+Test mode: Automated
+Test Tile: EthernetDstAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = dl_dst (say x) , action output to egress_port
+b) Send packet wth dl_dst = x
+c) Verify packet was recieved on egress_port
+d) Send packet with dl_dst = y
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+5. Single Header Field: Ethernet Type
+
+Test Description: Match on Ehternet Type and Wildcard rest
+
+Test mode: Automated
+Test Tile: EthernetType
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = dl_type (say x) , action output to egress_port
+b) Send packet wth dl_type = x
+c) Verify packet was recieved on egress_port
+d) Send packet with dl_type = y
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+6. Single Header Field: Vlan Id
+
+Test Description: Match on Ingress Port and Wildcard rest
+
+Test mode: Automated
+Test Tile: VlanId
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = dl_vlan (say x) , action output to egress_port
+b) Send a tagged packet with (dl_vlan_enable=True,dl_vlan = x)
+c) Verify packet was recieved on egress_port
+d) Send another tagged packet with (dl_vlan_enable=True,dl_vlan = y )
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+7. Single Header Field: Vlan PCP
+
+Test Description: Match on Vlan ID Priority
+
+Test mode: Automated
+Test Tile: VlanPcp
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = dl_vlan_pcp (say x) , action output to egress_port
+b) Send a tagged packet with (dl_vlan_enable=True, dl_vlan = * , dl_vlan_pcp = x)
+c) Verify packet was recieved on egress_port
+b) Send a tagged packet with (dl_vlan_enable=True, dl_vlan = * , dl_vlan_pcp = y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+
+8. Single Header Field: IP Src Address -------- > (TBD)
+
+Test Description: Match on IP Src Address and Wildcard rest
+
+Test mode: Automated
+Test Tile: IPSrcAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+
+
+9. Single Header Field: IP Dst Address -----------> (TBD)
+
+Test Description: Match on IP Dst Address and Wildcard rest
+
+Test mode: Automated
+Test Tile: IPDstAddress
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+
+
+
+10. Single Header Field: IP protocol---------------> (TBD)
+
+Test Description: Match on IP Protocol and Wildcard rest
+
+Test mode: Automated
+Test Tile: IPprotocol
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+
+
+
+
+11. Single Header Field: IP Tos bits
+
+Test Description: Match on IP Tos bits and Wildcard rest
+
+Test mode: Automated
+Test Tile: IpTos
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = nw_tos (say x) , action output to egress_port
+b) Send a tcp packet with (nw_tos=x)
+c) Verify packet was recieved on egress_port
+b) Send a tcp packet with (nw_tos = y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+12. Single Header Field: Transport Source Port
+
+Test Description: Match on Transport Src Port and Wildcard rest
+
+Test mode: Automated
+Test Tile: TcpSrcPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = tp_src (say x) , action output to egress_port
+b) Send a tcp packet with (tp_src=x)
+c) Verify packet was recieved on egress_port
+b) Send a tcp packet with tp_src= y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+13. Single Header Field: Transport Destination Port
+
+Test Description: Match on Transport Dst Port and Wildcard rest
+
+Test mode: Automated
+Test Tile: TcpDstPort
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = tp_dst (say x) , action output to egress_port
+b) Send a tcp packet with (tp_dst=x)
+c) Verify packet was recieved on egress_port
+b) Send a tcp packet with tp_dst = y)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+
+14. Multiple Header Fields: L2
+
+
+Test Description: Match on Ethernet Type, Ethernet Source Address, Ethernet Destination Address and Wildcard rest
+
+Test mode: Automated
+Test Tile: MultipleHeaderFieldL2
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = dl_type (say x), dl_src (say y ), dl_dst (say z), action output to egress_port
+b) Send a eth packet with dl_type (say x), dl_src (say y ), dl_dst (say z)
+c) Verify packet was recieved on egress_port
+b) Send a eth packet with dl_type (say w), dl_src (say v ), dl_dst (say f)
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+15. Multiple Header Fields: L3 ------> TBD
+
+
+
+
+16. Multiple Header Fields: L4
+
+Test Description: Match on Tcp Source Port, Tcp Destination Port
+
+Test mode: Automated
+Test Tile: MultipleHeaderFieldL4
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with match = tp_src (say x), tp_dst (say y )
+b) Send a tcp packet with tp_src (say x), tp_dst (say y )
+c) Verify packet was recieved on egress_port
+b) Send a eth packet with tcp_src (say w), tcp_dst (say v )
+e) Verify PacketIn event was triggered on the control plane
+
+
+
+17. All Header Fields: Exact Match flows
+
+Test Description: Verify exact flow matches are possible
+
+Test mode: Automated
+Test Tile: ExactMatch
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert a flow with exact match, action output to egress_port
+b) Send packet matching the flow
+c) Verify packet received on egress_port
+d) Send a non-matching packet
+e) Verify PacketIn event gets triggered
+
+
+
+18. Exact Match Highest Priority
+
+Test Description: An exact match flow entry has a highest priority compared to other flow entries
+
+Test mode: Automated
+Test Tile: ExactMatchHigh
+POrts: 4 (1 Control Plane 3 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert two overlapping flows:
+ Exact Match (prio = p ) action egress_port
+ Wildacrd All (prio = p+ ) action egress_port2
+b) Send packet matching the flows
+c) Verify packet received on egress_port
+
+
+
+
+19. Wildcard Match Highest Priority
+
+Test Description: If Wildcard flow entries have priority associated with them.
+ Higher priority Wildcard flow overrides the lower priroty Wildcard flow
+
+Test mode: Automated
+Test Tile: WildcardMatchHigh
+POrts: 4 (1 Control Plane 3 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
+
+
+Test Notes:
+
+a) Insert two wildcarded flows :
+ Wildcard All Except ingress (prio = p ) , action = egress_port
+ Wildcard All (prio = p+ ) ,action = egress_port2
+b) Send packet matching the flows
+c) Verify packet is recieved on egress_port2
+
+
+
+20. Fragment TCP Segments ------> TBD
+
+Test Description: Create flow matching on tcp port number. Verify that fragmented packets always match that flow rule.
+
+Test mode: Automated
+Test Tile: FragTcpSeg
+POrts: 3 (1 Control Plane 2 Data Plane)
+Initial State: Default (Clear switch state), Connection setup
+Test-Field: Mandatory
diff --git a/tests/FuncUtils.py b/tests/FuncUtils.py
index 61f285c..0ef9dc1 100644
--- a/tests/FuncUtils.py
+++ b/tests/FuncUtils.py
@@ -220,6 +220,43 @@
return (Pkt_MatchIngress,match3)
+def Wildcard_All_Except_Ingress1(self,of_ports,priority=0):
+# Generate Wildcard_All_Except_Ingress_port flow with action output to port egress_port 2
+
+
+ #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[2]
+ 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 Match_Vlan_Id(self,of_ports,priority=0):
#Generate Match_Vlan_Id
diff --git a/tests/flow_matches.py b/tests/flow_matches.py
new file mode 100644
index 0000000..891bb33
--- /dev/null
+++ b/tests/flow_matches.py
@@ -0,0 +1,633 @@
+"""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 6 --> Flow Matches"
+
+
+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 oftest.base_tests as base_tests
+import time
+
+from oftest.testutils import *
+from time import sleep
+from FuncUtils import *
+
+
+
+class AllWildcardMatch(base_tests.SimpleDataPlane):
+
+ """Verify for an all wildcarded flow all the injected packets would match that flow"""
+
+ def runTest(self):
+
+ logging.info("Running All Wildcard Match test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting an all wildcarded flow and sending packets with various match fields")
+ logging.info("Expecting all sent packets to match")
+
+ #Insert an All Wildcarded flow.
+ Wildcard_All(self,of_ports)
+
+ #check for different match fields and verify packet implements the action specified in the flow
+ pkt1 = simple_tcp_packet(dl_src="00:01:01:01:01:01");
+ self.dataplane.send(of_ports[0], str(pkt1))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt1,[yes_ports],no_ports,self)
+
+ pkt2 = simple_tcp_packet(dl_dst="00:01:01:01:01:01");
+ self.dataplane.send(of_ports[0], str(pkt2))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt2,[yes_ports],no_ports,self)
+
+ pkt3 = simple_tcp_packet(ip_src="192.168.2.1");
+ self.dataplane.send(of_ports[0], str(pkt3))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt3,[yes_ports],no_ports,self)
+
+ pkt4 = simple_tcp_packet(ip_dst="192.168.2.2");
+ self.dataplane.send(of_ports[0], str(pkt4))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt4,[yes_ports],no_ports,self)
+
+ pkt5 = simple_tcp_packet(ip_tos=2);
+ self.dataplane.send(of_ports[0], str(pkt5))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt5,[yes_ports],no_ports,self)
+
+ pkt6 = simple_tcp_packet(tcp_sport=8080);
+ self.dataplane.send(of_ports[0], str(pkt6))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt6,[yes_ports],no_ports,self)
+
+ pkt7 = simple_tcp_packet(tcp_dport=8081);
+ self.dataplane.send(of_ports[0], str(pkt7))
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt7,[yes_ports],no_ports,self)
+
+
+
+class EthernetSrcAddress(base_tests.SimpleDataPlane):
+
+ """Verify match on single header field -- Ethernet Src Address """
+
+ def runTest(self):
+
+ logging.info("Running Ethernet Src Address test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Ethernet Source Address ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Insert a Match On Ethernet Src Address flow
+ (pkt,match) = Match_Ethernet_Src_Address(self,of_ports)
+
+ #Sending packet matching the flow, verify it implements the action
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet , verify Packetin event gets triggered.
+ pkt2 = simple_tcp_packet(dl_src='00:01:01:01:01:02');
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+class EthernetDstAddress(base_tests.SimpleDataPlane):
+
+ """Verify match on single Header Field Field -- Ethernet Dst Address """
+
+ def runTest(self):
+
+ logging.info("Running Ethernet Dst Address test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Ethernet Destination Address ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Insert a Match on Destination Address flow
+ (pkt,match) = Match_Ethernet_Dst_Address(self,of_ports)
+
+ #Send Packet matching the flow
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Send Non-matching packet
+ pkt2 = simple_tcp_packet(dl_dst='00:01:01:01:01:02');
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ #Verify PacketIn event gets triggered
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+
+class EthernetType(base_tests.SimpleDataPlane):
+
+ """Verify match on single header field -- Ethernet Type """
+
+ def runTest(self):
+
+ logging.info("Running Ethernet Type test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Ethernet Type ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Insert a Match on Ethernet Type flow
+ (pkt,match) = Match_Ethernet_Type(self,of_ports)
+
+ #Sending packet matching the flow
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet ,
+ pkt2 = simple_eth_packet(dl_type=0x0806);
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ #verify Packetin event gets triggered.
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+
+class IngressPort(base_tests.SimpleDataPlane):
+
+ """Verify match on single Header Field Field -- In_port """
+
+ def runTest(self):
+
+ logging.info("Running Ingress Port test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Ingress Port ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Insert a Match on Ingress Port FLow
+ (pkt,match) = Wildcard_All_Except_Ingress(self,of_ports,priority=0)
+
+ #Send Packet matching the flow i.e on in_port specified in the flow
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Send Non-Matching Packet
+ self.dataplane.send(of_ports[1],str(pkt))
+
+ #Verify PacketIn event gets triggered
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+class VlanId(base_tests.SimpleDataPlane):
+
+ """Verify match on single Header Field Field -- Vlan Id """
+
+ def runTest(self):
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on VLAN ID ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Create a flow with match on Vlan Id
+ (pkt,match) = Match_Vlan_Id(self,of_ports)
+
+ #Send tagged packet matching the flow i.e packet with same vlan id as in flow
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Send Non-matching packet, i.e packet with different Vlan Id
+ pkt2 = simple_tcp_packet(dl_vlan_enable=True,dl_vlan=4);
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ #Verify PacketIn event gets triggered
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+class VlanPCP(base_tests.SimpleDataPlane):
+
+ """"Verify match on single Header Field Field -- Vlan Priority"""
+
+ def runTest(self):
+
+ logging.info("Running VlanPCP1 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on VLAN Priority ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Create a flow matching on VLAN Priority
+ (pkt,match) = Match_Vlan_Pcp(self,of_ports)
+
+ #Send tagged Packet matching the flow
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Send tagged packet with same vlan_id but different vlan priority
+ pkt2 = simple_tcp_packet(dl_vlan_enable=True,dl_vlan=1,dl_vlan_pcp=20);
+ self.dataplane.send(in_port, str(pkt))
+
+class MultipleHeaderFieldL2(base_tests.SimpleDataPlane):
+
+ """Verify match on multiple header field -- Ethernet Type, Ethernet Source Address, Ethernet Destination Address """
+
+ def runTest(self):
+
+ logging.info("Running Multiple Header Field L2 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Multiple Header Field L2 ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ (pkt,match) = Match_Mul_L2(self,of_ports)
+
+ #Send eth packet matching the dl_type field, verify it implements the action
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet , verify Packetin event gets triggered.
+ pkt2 = simple_eth_packet(dl_type=0x0806,dl_src='00:01:01:01:01:02',dl_dst='00:01:01:01:01:01');
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+class IpTos(base_tests.SimpleDataPlane):
+
+ """"Verify match on single Header Field Field -- Type of service"""
+
+ def runTest(self):
+
+ logging.info("Running Ip_Tos test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rv = delete_all_flows(self.controller)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Ip_Tos ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ #Create a flow matching on VLAN Priority
+ (pkt,match) = Match_Ip_Tos(self,of_ports)
+
+ #Send Packet matching the flow
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Create a non-matching packet , verify packet_in get generated
+ pkt2 = simple_tcp_packet(ip_tos=20);
+ self.dataplane.send(of_ports[0], str(pkt2))
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+
+class TcpSourcePort(base_tests.SimpleDataPlane):
+
+ """Verify match on Single header field -- Tcp Source Port, """
+
+ def runTest(self):
+
+ logging.info("Running Tcp Source Port test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Tcp Tcp Source Port ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ (pkt,match) = Match_Tcp_Src(self,of_ports)
+
+ #Sending packet matching the tcp_sport, verify it implements the action
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet , verify Packetin event gets triggered.
+ pkt2 = simple_tcp_packet(tcp_sport=540);
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+class TcpDstPort(base_tests.SimpleDataPlane):
+
+ """Verify match on Single header field -- Tcp Destination Port """
+
+ def runTest(self):
+
+ logging.info("Running Tcp Destination Port test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Tcp Destination Port ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ (pkt,match) = Match_Tcp_Dst(self,of_ports)
+
+ #Sending packet matching the tcp_dport, verify it implements the action
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet , verify Packetin event gets triggered.
+ pkt2 = simple_tcp_packet(tcp_dport=541);
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=10)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+
+class ExactMatch(base_tests.SimpleDataPlane):
+
+ """Verify match on Single header field -- Exact Match """
+
+ def runTest(self):
+
+ logging.info("Running Tcp Exact Match test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match for Exact Match ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ (pkt,match) = Exact_Match(self,of_ports)
+
+ #Sending packet matching all the fields of a tcp_packet, verify it implements the action
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet , verify Packetin event gets triggered.
+ pkt2 = simple_tcp_packet(tcp_sport=540);
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+
+class MultipleHeaderFieldL4(base_tests.SimpleDataPlane):
+
+ """Verify match on multiple header field -- Tcp Source Port, Tcp Destination Port """
+
+ def runTest(self):
+
+ logging.info("Running Multiple Header Field L4 test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with match on Multiple Header Field L4 ")
+ logging.info("Sending matching and non-matching packets")
+ logging.info("Verifying matching packets implements the action specified in the flow")
+
+ (pkt,match) = Match_Mul_L4(self,of_ports)
+
+ #Sending packet matching the tcp_sport and tcp_dport field, verify it implements the action
+ self.dataplane.send(of_ports[0], str(pkt))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+ #Sending non matching packet , verify Packetin event gets triggered.
+ pkt2 = simple_tcp_packet(tcp_sport=540,tcp_dport=541);
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,timeout=4)
+ self.assertTrue(response is not None, "PacketIn not received")
+
+
+
+class ExactMatchHigh(base_tests.SimpleDataPlane):
+
+ """Verify that Exact Match has highest priority """
+
+ def runTest(self):
+
+ logging.info("Running Exact Match High Priority test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting a flow with Exact Match (low priority)")
+ logging.info("Inserting a overlapping wildcarded flow (higher priority)")
+ logging.info("Sending packets matching both the flows ")
+ logging.info("Verifying matching packets implements the action specified in the exact match flow")
+
+ #Insert two Overlapping Flows : Exact Match and Wildcard All.
+ (pkt,match) = Exact_Match_With_Prio(self,of_ports,priority=10)
+ (pkt2,match2) = Wildcard_All(self,of_ports,priority=20);
+
+ #Sending packet matching the both the flows , verify it implements the action specified in Exact Match Flow
+ self.dataplane.send(of_ports[0], str(pkt2))
+
+ #Verify packet implements the action specified in the flow
+ egress_port=of_ports[2]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = egress_port
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
+
+
+class WildcardMatchHigh(base_tests.SimpleDataPlane):
+
+ """Verify that Wildcard Match with highest priority overrides the low priority WildcardMatch """
+
+ def runTest(self):
+
+ logging.info("Running Wildcard Match High Priority test")
+
+ of_ports = config["port_map"].keys()
+ of_ports.sort()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+
+ #Clear Switch State
+ rc = delete_all_flows(self.controller)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ logging.info("Inserting two wildcarded flows with priorities ")
+ logging.info("Sending packets matching the flows")
+ logging.info("Verifying matching packets implements the action specified in the flow with higher priority")
+
+ (pkt,match) = Wildcard_All(self,of_ports,priority=20)
+ (pkt1,match1) = Wildcard_All_Except_Ingress1(self,of_ports,priority=10)
+
+ #Sending packet matching both the flows , verify it implements the action specified by Higher Priority flow
+ self.dataplane.send(of_ports[0], str(pkt1))
+
+ egress_port=of_ports[1]
+ no_ports=set(of_ports).difference([egress_port])
+ yes_ports = of_ports[1]
+ receive_pkt_check(self.dataplane,pkt,[yes_ports],no_ports,self)
\ No newline at end of file