Changes to add a switch-type option for qumran based switches.

Change-Id: I28a9c622b058a9a201a1307a55342272a06ec0fc
diff --git a/README.md b/README.md
index 0ffe6fe..1e4d8ff 100755
--- a/README.md
+++ b/README.md
@@ -79,41 +79,47 @@
 	sudo ./oft -V1.3 --test-dir=ofdpa flows.PacketInArp -i 24@eth1 -i 12@eth2
 	```
 
+* Run specific test case for a specific switch type (only special case of switch type supported are Qumran based switches)
+
+	```
+	sudo ./oft -V1.3 -Y qmx --test-dir=ofdpa flows.PacketInArp -i 24@eth1 -i 12@eth2
+	```
+
 ---
 
 # Test Result Summary
 
 The following tests are implemented and these are their results.
 
-Test Results       | i12_1.7 | 2.0 GA | 3.0 EA0 | 3.0 EA4 |
--------            | ------- | ------ | ------- | ------- |
-/0Ucast            | X       | ok     | ok      | ok      |
-/24UnicastTagged   | ok      | ok     | ok      | ok      |
-/32UnicastTagged   | ok      | ok     | ok      | ok      |
-/24ECMPL3          | ok      | ok     | ok      | ok      |
-/32ECMPL3          | ok      | ok     | ok      | ok      |
-/24ECMPVPN         | ok      | ok     | ok      | ok~      |
-/32ECMPVPN         | ok      | ok     | ok      | ok~      |
-/32VPN             | ok      | ok     | ok      | ok~      |
-/24VPN             | ok      | ok     | ok      | ok~      |
-EcmpGroupMod       | X       | X      | ok      | ok      |
-PacketInArp        | ok      | ok     | ok      | ok      |
-MTU1500            | ok      | ok     | ok      | ok      |
-MplsTermination    | ok      | ok     | ok      | ok~      |
-MplsFwd            | X       | ok     | ok      | ok~      |
-L2FloodQinQ        | ok      | ok     | ok      | ok      |
-L2UnicastTagged    | ok      | ok     | ok      | ok      |
-L3McastToL3        | ok      | X      | ok      | ok      |
-L3McastToL2_1*     | ?       | ?      | ok      | ok      |
-L3McastToL2_2**    | ?       | ?      | ok      | ok      |
-L3McastToL2_3***   | ?       | ?      | ok      | ok      |
-L3McastToL2_4****  | ok      | ?      | ok      | ok      |
-L3McastToL2_5***** | ?       | ?      | ok      | ok      |
-FloodGroupMod      | X       | X      | ok      | ok      |
-PacketInUDP        | ok      | ok     | ok      | ok      |
-Unfiltered         | X       | ok     | X       | ok      |
-Untagged           | ok      | n/a    | ok      | ok      |
-PacketInIPTable    | X       | X      | ok      | ok~      |
+Test Results       | i12_1.7 | 2.0 GA | 3.0 EA0 | 3.0 EA4 | 3.0 EA4 QMX |
+-------            | ------- | ------ | ------- | ------- |-------------
+/0Ucast            | X       | ok     | ok      | ok      | X           |
+/24UnicastTagged   | ok      | ok     | ok      | ok      | X           |
+/32UnicastTagged   | ok      | ok     | ok      | ok      | X           |
+/24ECMPL3          | ok      | ok     | ok      | ok      | X           |
+/32ECMPL3          | ok      | ok     | ok      | ok      | X           |
+/24ECMPVPN~        | ok      | ok     | ok      | ok      | X           |
+/32ECMPVPN~        | ok      | ok     | ok      | ok      | X           |
+/32VPN~            | ok      | ok     | ok      | ok      | X           |
+/24VPN~            | ok      | ok     | ok      | ok      | X           |
+EcmpGroupMod       | X       | X      | ok      | ok      | X           |
+PacketInArp        | ok      | ok     | ok      | ok      | ok          |
+MTU1500            | ok      | ok     | ok      | ok      | ok          |
+MplsTermination~   | ok      | ok     | ok      | ok      | X           |
+MplsFwd~           | X       | ok     | ok      | ok      | ok          |
+L2FloodQinQ        | ok      | ok     | ok      | ok      | X           |
+L2UnicastTagged    | ok      | ok     | ok      | ok      | ok          |
+L3McastToL3        | ok      | X      | ok      | ok      | X           |
+L3McastToL2_1*     | ?       | ?      | ok      | ok      | X           |
+L3McastToL2_2**    | ?       | ?      | ok      | ok      | X           |
+L3McastToL2_3***   | ?       | ?      | ok      | ok      | X           |
+L3McastToL2_4****  | ok      | ?      | ok      | ok      | X           |
+L3McastToL2_5***** | ?       | ?      | ok      | ok      | X           |
+FloodGroupMod      | X       | X      | ok      | ok      | X           |
+PacketInUDP        | ok      | ok     | ok      | ok      | ok          |
+Unfiltered         | X       | ok     | X       | ok      | ok          |
+Untagged           | ok      | n/a    | ok      | ok      | ok          |
+PacketInIPTable~   | X       | X      | ok      | ok      | X           |
 
 ```
 ~       Tests marked with tilda are currently disabled because of a bug which causes
diff --git a/ofdpa/flows.py b/ofdpa/flows.py
index ac99b9b..6e416de 100755
--- a/ofdpa/flows.py
+++ b/ofdpa/flows.py
@@ -210,7 +210,7 @@
         Groups = Queue.LifoQueue( )
         try:
             ports = sorted( config[ "port_map" ].keys( ) )
-            vlan_id = 1
+            vlan_id = 100
 
             for port in ports:
                 L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
@@ -245,6 +245,7 @@
             delete_all_groups( self.controller )
 
 
+
 @disabled
 class L2FloodTagged( base_tests.SimpleDataPlane ):
     """
@@ -372,14 +373,13 @@
             if len( config[ "port_map" ] ) < 2:
                 logging.info( "Port count less than 2, can't run this case" )
                 return
-
             intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
             ports = config[ "port_map" ].keys( )
             for port in ports:
-                # add l2 interface group
                 vlan_id = port + test_id
+                # add l2 interface group and l3 unicast group
                 l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
                         is_tagged=True, send_barrier=False )
                 dst_mac[ 5 ] = vlan_id
@@ -388,7 +388,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add unicast routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, l3_msg.group_id )
@@ -458,7 +461,10 @@
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=2,
                         flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, mpls_label_gid, vrf=2 )
@@ -528,7 +534,10 @@
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=0,
                         flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id )
@@ -604,7 +613,10 @@
             add_one_vlan_table_flow( self.controller, ports[0], 1, vlan_id=ports[0] + in_offset, vrf=0,
                                      flag=VLAN_TABLE_FLAG_ONLY_TAG )
             # add termination flow
-            add_termination_flow( self.controller, ports[0], 0x0800, intf_src_mac, vlanid=ports[0] + in_offset )
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlanid=ports[0] + in_offset )
+            else:
+                add_termination_flow( self.controller, ports[0], 0x0800, intf_src_mac, vlanid=ports[0] + in_offset )
             # add routing flow
             dst_ip = dip + (vlan_id << 8)
             add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id, send_barrier=True )
@@ -672,7 +684,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add unicast routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id )
@@ -741,7 +756,10 @@
             # add vlan flow table
             add_one_vlan_table_flow( self.controller, of_port=inport, vlan_id=inport+in_offset, flag=VLAN_TABLE_FLAG_ONLY_TAG )
             # add termination flow
-            add_termination_flow( self.controller, in_port=inport, eth_type=0x0800, dst_mac=intf_src_mac, vlanid=inport+in_offset )
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlanid=inport+in_offset )
+            else:
+                add_termination_flow( self.controller, in_port=inport, eth_type=0x0800, dst_mac=intf_src_mac, vlanid=inport+in_offset )
             # add unicast routing flow
             dst_ip = dip + (vlan_id << 8)
             add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, ecmp_msg.group_id, send_barrier=True )
@@ -806,7 +824,10 @@
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=0,
                         flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, mpls_label_gid )
@@ -873,7 +894,10 @@
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, vrf=0,
                         flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add routing flow
                 dst_ip = dip + (vlan_id << 8)
                 # add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_label_gid, vrf=2)
@@ -989,7 +1013,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add unicast routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id )
@@ -1048,7 +1075,10 @@
             # add vlan flow table
             add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH )
             # add termination flow
-            add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x08847, intf_src_mac, vlan_id, goto_table=24 )
+            else:
+                add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
             # add mpls flow
             add_mpls_flow( self.controller, l3_msg.group_id, port )
             # add termination flow
@@ -1541,7 +1571,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                else:
+                    add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
                 #add_mpls_flow( self.controller, ecmp_gid, port, goto_table=29 )
                 add_mpls_flow( self.controller, mpls_label_gid, mpls_label, goto_table=29 )
                 dst_ip = dip + (vlan_id << 8)
@@ -1615,7 +1648,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
+                else:
+                    add_termination_flow( self.controller, port, 0x8847, intf_src_mac, vlan_id, goto_table=24 )
                 add_mpls_flow( self.controller, ecmp_msg.group_id, mpls_label )
                 # add_mpls_flow(self.controller, label=port)
                 dst_ip = dip + (vlan_id << 8)
@@ -1693,7 +1729,10 @@
             # add vlan flow table
             add_one_vlan_table_flow( self.controller, inport, 1, invlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
             # add tmac flow
-            add_termination_flow( self.controller, inport, 0x8847, intf_src_mac, invlan_id, goto_table=24 )
+            if config["switch_type"] == "qmx":
+                add_termination_flow( self.controller, 0, 0x8847, intf_src_mac, invlan_id, goto_table=24 )
+            else:
+                add_termination_flow( self.controller, inport, 0x8847, intf_src_mac, invlan_id, goto_table=24 )
             # add mpls termination flow
             add_mpls_flow( self.controller, ecmp_msg.group_id, mpls_label, send_barrier=True )
             Groups._put( l2_gid )
@@ -1752,7 +1791,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add unicast routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, l3_msg.group_id )
@@ -1812,7 +1854,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add unicast routing flow
                 dst_ip = dip + (vlan_id << 8)
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, l3_msg.group_id )
@@ -2027,7 +2072,10 @@
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
-                add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
+                if config["switch_type"] == "qmx":
+                    add_termination_flow( self.controller, 0, 0x0800, intf_src_mac, vlan_id )
+                else:
+                    add_termination_flow( self.controller, port, 0x0800, intf_src_mac, vlan_id )
                 # add unicast routing flow
                 dst_ip = dip + (vlan_id << 8)
                 dst_ips += [dst_ip]
diff --git a/oft b/oft
index 275e3d3..297c3f3 100755
--- a/oft
+++ b/oft
@@ -72,6 +72,7 @@
     "controller_host"    : "0.0.0.0",  # For passive bind
     "controller_port"    : 6653,
     "switch_ip"          : None,  # If not none, actively connect to switch
+    "switch_type"          : None,  # If not none, adapt flows to pipeline differences for switch type
     "platform"           : "eth",
     "platform_args"      : None,
     "platform_dir"       : os.path.join(ROOT_DIR, "platforms"),
@@ -173,6 +174,8 @@
                       type="int", help="Port number to listen on (default %default)")
     group.add_option("-S", "--switch-ip", dest="switch_ip",
                       help="If set, actively connect to this switch by IP")
+    group.add_option("-Y", "--switch-type", dest="switch_type",
+                      help="If set to qmx, flows will adapt to pipline differences")
     group.add_option("-P", "--platform", help="Platform module name (default %default)")
     group.add_option("-a", "--platform-args", help="Custom arguments for the platform")
     group.add_option("--platform-dir", type="string", help="Directory containing platform modules")