Added end to end test of fabric
diff --git a/ofdpa/accton_util.py b/ofdpa/accton_util.py
index e5a7e41..fabcab7 100755
--- a/ofdpa/accton_util.py
+++ b/ofdpa/accton_util.py
@@ -421,11 +421,15 @@
             match = ofp.match()
             match.oxm_list.append(ofp.oxm.in_port(of_port))
             match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
             request = ofp.message.flow_add(
                 table_id=10,
                 cookie=42,
                 match=match,
                 instructions=[
+                  ofp.instruction.apply_actions(
+                     actions=actions
+                  ),
                   ofp.instruction.goto_table(20)
                 ],
                 priority=0)
diff --git a/ofdpa/onos.py b/ofdpa/onos.py
index cac61c1..283ca7d 100644
--- a/ofdpa/onos.py
+++ b/ofdpa/onos.py
@@ -30,16 +30,15 @@
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
 
+        ports = sorted(config["port_map"].keys())
+        for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
         parsed_vlan_pkt = simple_tcp_packet(pktlen=104,
                       vlan_vid=0x1001, dl_vlan_enable=True)
         vlan_pkt = str(parsed_vlan_pkt)
 
-        add_vlan_table_flow(self.controller, config["port_map"].keys(), 1)
-
-        # group table
-        # set up untag groups for each port
-        add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  True, 1)
-
         for of_port in config["port_map"].keys():
             logging.info("PacketInMiss test, port %d", of_port)
             self.dataplane.send(of_port, vlan_pkt)
@@ -56,20 +55,19 @@
     """
     def runTest(self):
         ports = sorted(config["port_map"].keys())
+
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
 
-        add_vlan_table_flow(self.controller, ports, 1)
-
-        # set up tagged groups for each port
-        add_l2_interface_grouop(self.controller, ports, 1,  True, 1)
-
-        msg=add_l2_flood_group(self.controller, ports, 1, 1)
-        add_bridge_flow(self.controller, None, 1, msg.group_id, True)
         # Installing flows to avoid packet-in
         for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+
             group_id = encode_l2_interface_group_id(1, port)
             add_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, port], 1, group_id, True)
+        msg=add_l2_flood_group(self.controller, ports, 1, 1)
+        add_bridge_flow(self.controller, None, 1, msg.group_id, True)  
         do_barrier(self.controller)
 
         #verify flood
@@ -95,14 +93,13 @@
     #todo take in account unknown src 
     """
     def runTest(self):
-        ports = sorted(config["port_map"].keys())
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
 
-        add_vlan_table_flow(self.controller, ports, 1)
-
-        # set up tagged groups for each port
-        add_l2_interface_grouop(self.controller, ports, 1,  True, 1)
+        ports = sorted(config["port_map"].keys())
+        for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)
 
         msg=add_l2_flood_group(self.controller, ports, 1, 1)
         add_bridge_flow(self.controller, None, 1, msg.group_id, True)
@@ -135,12 +132,9 @@
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
 
-        add_vlan_table_flow(self.controller, config["port_map"].keys())
-
-        # set up tag groups for each port
-        add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1, True, 1)
-
         for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)  
             group_id = encode_l2_interface_group_id(1, port)
             add_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, port], 1, group_id, True)
         do_barrier(self.controller)
@@ -174,12 +168,9 @@
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
 
-        add_vlan_table_flow(self.controller, config["port_map"].keys())
-
-        # set up tag groups for each port
-        add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1, True, 1)
-
         for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)
             group_id = encode_l2_interface_group_id(1, port)
             add_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, port], 1, group_id, True)
         do_barrier(self.controller)
@@ -213,12 +204,14 @@
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
 
-        add_vlan_table_flow(self.controller, config["port_map"].keys())
+       # set up tag groups for each port
+        add_l2_interface_grouop(self.controller, ports, 1, True, 1)
 
-        # set up tag groups for each port
-        add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1, True, 1)
+        add_vlan_table_flow(self.controller, ports)
 
         for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)
             group_id = encode_l2_interface_group_id(1, port)
             add_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, port], 1, group_id, True)
         do_barrier(self.controller)
@@ -263,6 +256,8 @@
         add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1, True, 1)
 
         for port in ports:
+            add_one_l2_interface_grouop(self.controller, port, 1, True, False)
+            add_one_vlan_table_flow(self.controller, port, 1, flag=VLAN_TABLE_FLAG_ONLY_TAG)
             group_id = encode_l2_interface_group_id(1, port)
             add_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, port], 1, group_id, True)
         do_barrier(self.controller)
@@ -311,7 +306,7 @@
             dst_mac[5]=vlan_id
             l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=intf_src_mac, dst_mac=dst_mac)
             #add vlan flow table
-            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)
+            add_one_vlan_table_flow(self.controller, port, vlan_id,  flag=VLAN_TABLE_FLAG_ONLY_TAG)
             #add termination flow
             add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)
             #add unicast routing flow
@@ -366,7 +361,7 @@
         for port in ports:
             #add l2 interface group
             vlan_id=port
-            l2_gid, l2_msg = add_one_l2_interface_grouop(self.controller, port, vlan_id, True, False)
+            l2_gid, l2_msg = add_one_l2_interface_grouop(self.controller, port, vlan_id, True, True)
             dst_mac[5]=vlan_id
             #add MPLS interface group
             mpls_gid, mpls_msg = add_mpls_intf_group(self.controller, l2_gid, dst_mac, intf_src_mac, vlan_id, port)
@@ -374,12 +369,12 @@
             mpls_label_gid, mpls_label_msg = add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL,
 		     index=port, ref_gid= mpls_gid, push_mpls_header=True, set_mpls_label=port, set_bos=1, set_ttl=32)
             #add vlan flow table
-            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)
+            add_one_vlan_table_flow(self.controller, port, vlan_id, vrf=2, flag=VLAN_TABLE_FLAG_ONLY_BOTH)
             #add termination flow
             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)
+            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_label_gid, vrf=2)
             #add entries in the Bridging table to avoid packet-in from mac learning
             group_id = encode_l2_interface_group_id(vlan_id, port)
             add_bridge_flow(self.controller, dst_mac, vlan_id, group_id, True)
@@ -402,17 +397,17 @@
                 #build expect packet
                 mac_dst='00:00:00:22:22:%02X' % out_port
                 label = (out_port, 0, 1, 32)
-                exp_pkt = mpls_packet(dl_vlan_enable=True, vlan_vid=out_port, ip_ttl=64, ip_src=ip_src,
+                exp_pkt = mpls_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=out_port, ip_ttl=63, ip_src=ip_src,
                             ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac, label=[label])
                 pkt=str(exp_pkt)
                 verify_packet(self, pkt, out_port)
                 verify_no_other_packets(self)
 
 class MplsTermination(base_tests.SimpleDataPlane):
-    '''
+    """
 	Insert IP packet
 	Receive MPLS packet
-    '''
+    """
     def runTest(self):
         delete_all_flows(self.controller)
         delete_all_groups(self.controller)
@@ -471,3 +466,4 @@
                 verify_packet(self, pkt, out_port)
                 verify_no_other_packets(self)
 
+
diff --git a/ofdpa/sr.py b/ofdpa/sr.py
new file mode 100644
index 0000000..2c6b34c
--- /dev/null
+++ b/ofdpa/sr.py
@@ -0,0 +1,207 @@
+
+from oftest import config
+import logging
+import oftest.base_tests as base_tests
+import ofp
+from oftest.testutils import *
+from accton_util import *
+
+class Leaf1(base_tests.SimpleDataPlane):
+
+    def runTest(self):
+     #Add flows correspondent to Leaf1
+     switch_mac=[0x00, 0x00, 0x00, 0x01, 0xea, 0xf1]
+     dst_mac= [0x00, 0x00, 0x00, 0x12, 0x34, 0x01]
+     #Add L3Unicast to Host
+     port, vlan_id = 33, 10
+     ##add L2 Interface Group
+     add_one_l2_interface_grouop(self.controller, port, vlan_id=vlan_id, is_tagged=True, send_barrier=False)
+     ##add L3 Unicast Group
+     l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=switch_mac, 
+                                dst_mac=dst_mac)
+     add_one_vlan_table_flow(self.controller, of_port=port, vlan_id=vlan_id, vrf=vlan_id,
+                             flag=VLAN_TABLE_FLAG_ONLY_TAG)
+     ##add Termination Flow
+     add_termination_flow(self.controller, port, 0x0800, switch_mac, vlan_id)
+     ##add unicast routing flow
+     dst_ip=0x0a000001
+     mask=0xffffff00
+     add_unicast_routing_flow(self.controller, 0x0800, dst_ip, mask, l3_msg.group_id, vrf=10)
+     #add entries in the Bridging table to avoid packet-in from mac learning
+     group_id = encode_l2_interface_group_id(vlan_id, port)
+     add_bridge_flow(self.controller, dst_mac, vlan_id, group_id, True)
+
+     port = 32
+     add_one_l2_interface_grouop(self.controller, port, vlan_id=vlan_id, is_tagged=True, send_barrier=False)
+     add_one_vlan_table_flow(self.controller, port, vlan_id, vrf=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+     add_termination_flow(self.controller, port, 0x0800, switch_mac, vlan_id)
+     do_barrier(self.controller)
+
+     #Add L3VPN initiation
+     dst_mac = [0x00, 0x00, 0x00, 0x55, 0x55, 0x55]
+     vlan_id = 100
+     ##add L2 Interface Group
+     l2_gid, l2_msg = add_one_l2_interface_grouop(self.controller, port, vlan_id=vlan_id, is_tagged=True, send_barrier=False) 
+     #add MPLS interface group
+     mpls_gid, mpls_msg = add_mpls_intf_group(self.controller, l2_gid, dst_mac, switch_mac, vlan_id, port)
+     ##add L3VPN interface
+     mpls_label_gid, mpls_label_msg = add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL,
+	 index=port, ref_gid= mpls_gid, push_mpls_header=True, set_mpls_label=20, set_bos=1, set_ttl=32)
+     ##add unicast routing flow
+     dst_ip=0x14000001
+     add_unicast_routing_flow(self.controller, 0x0800, dst_ip, mask, mpls_label_gid, vrf=10)
+   
+     #add entries in the Bridging table to avoid packet-in from mac learning
+     group_id = encode_l2_interface_group_id(vlan_id, port)
+     add_bridge_flow(self.controller, dst_mac, vlan_id, group_id, True)
+ 
+     do_barrier(self.controller)
+
+class Leaf2(base_tests.SimpleDataPlane):
+
+  def runTest(self):  
+     #Add flows correspondent to Leaf2
+     switch_mac=[0x00, 0x00, 0x00, 0x01, 0xea, 0xf2]
+     dst_mac= [0x00, 0x00, 0x00, 0x12, 0x34, 0x02]
+     #Add L3Unicast to Host
+     port, vlan_id=33, 20
+     ##add L2 Interface Group
+     add_one_l2_interface_grouop(self.controller, port,  vlan_id=vlan_id, is_tagged=True, send_barrier=False) 
+     ##add L3 Unicast Group
+     l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=switch_mac,
+                                dst_mac=dst_mac)
+     add_one_vlan_table_flow(self.controller, port, vlan_id, vrf=20, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+     ##add Termination Flow
+     add_termination_flow(self.controller, port, 0x0800, switch_mac, vlan_id)
+     ##add unicast routing flow
+     dst_ip=0x14000001
+     mask=0xffffff00
+     add_unicast_routing_flow(self.controller, 0x0800, dst_ip, mask, l3_msg.group_id, vrf=vlan_id)
+     #add entries in the Bridging table to avoid packet-in from mac learning
+     group_id = encode_l2_interface_group_id(vlan_id, port)
+     add_bridge_flow(self.controller, dst_mac, vlan_id, group_id, True)
+
+     port = 32
+     add_one_l2_interface_grouop(self.controller, port,  vlan_id=vlan_id, is_tagged=True, send_barrier=False) 
+     add_one_vlan_table_flow(self.controller, port, vlan_id, vrf=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+     add_termination_flow(self.controller, port, 0x0800, switch_mac, vlan_id)
+     do_barrier(self.controller)
+
+     #Add L3VPN initiation
+     dst_mac= [0x00, 0x00, 0x00, 0x55, 0x55, 0x55]
+     vlan_id = 100
+     ##add L2 Interface Group
+     l2_gid, l2_msg = add_one_l2_interface_grouop(self.controller, port,  vlan_id=vlan_id, is_tagged=True, send_barrier=False) 
+     #add MPLS interface group
+     mpls_gid, mpls_msg = add_mpls_intf_group(self.controller, l2_gid, dst_mac, switch_mac, vlan_id, port)
+     ##add L3VPN interface
+     mpls_label_gid, mpls_label_msg = add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL,  
+         index=port, ref_gid= mpls_gid, push_mpls_header=True, set_mpls_label=10, set_bos=1, set_ttl=32)
+     ##add unicast routing flow
+     dst_ip=0x0a000001
+     add_unicast_routing_flow(self.controller, 0x0800, dst_ip, mask, mpls_label_gid, vrf=20)
+     #add entries in the Bridging table to avoid packet-in from mac learning
+     group_id = encode_l2_interface_group_id(vlan_id, port)
+     add_bridge_flow(self.controller, dst_mac, vlan_id, group_id, True)
+
+class Spine(base_tests.SimpleDataPlane):
+
+  def runTest(self):  
+     #add Spine Flows
+     switch_mac = [0x00, 0x00, 0x00, 0x55, 0x55, 0x55]
+     dst_mac = [0x00, 0x00, 0x00, 0x01, 0xea, 0xf1]
+     #Add MPLS termination 
+     port, vlan_id=31, 10 
+     ##add L2 Interface Group
+     add_one_l2_interface_grouop(self.controller, port,  vlan_id=vlan_id, is_tagged=True, send_barrier=False) 
+     ##add L3 Unicast Group
+     l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=switch_mac,
+                                dst_mac=dst_mac)
+     ecmp_msg = add_l3_ecmp_group(self.controller, port, [l3_msg.group_id])
+     vlan_id=100
+     add_one_vlan_table_flow(self.controller, of_port=port, vlan_id=100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+     add_termination_flow(self.controller, port, 0x8847, switch_mac, vlan_id, goto_table=24)
+     add_mpls_flow(self.controller, ecmp_msg.group_id, 10)
+     #add entries in the Bridging table to avoid packet-in from mac learning
+     group_id = encode_l2_interface_group_id(100, port)
+     add_bridge_flow(self.controller, dst_mac, 100, group_id, True)
+     
+     dst_mac = [0x00, 0x00, 0x00, 0x01, 0xea, 0xf2]
+     #Add MPLS termination
+     port, vlan_id=32, 20
+     ##add L2 Interface Group
+     add_one_l2_interface_grouop(self.controller, port,  vlan_id=vlan_id, is_tagged=True, send_barrier=False) 
+     ##add L3 Unicast Group
+     l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=switch_mac,
+                                dst_mac=dst_mac)
+     ecmp_msg = add_l3_ecmp_group(self.controller, port, [l3_msg.group_id])
+     add_one_vlan_table_flow(self.controller, of_port=port, vlan_id=100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
+     vlan_id=100
+     add_termination_flow(self.controller, port, 0x8847, switch_mac, vlan_id, goto_table=24)
+     add_mpls_flow(self.controller, ecmp_msg.group_id, 20)
+     #add entries in the Bridging table to avoid packet-in from mac learning
+     group_id = encode_l2_interface_group_id(100, port)
+     add_bridge_flow(self.controller, dst_mac, 100, group_id, True)
+
+class TestLeaf1(base_tests.SimpleDataPlane):
+
+  def runTest(self): 
+        host_mac='00:00:00:12:34:01'
+        ip_src='10.0.0.1'
+        ip_dst='20.0.0.2'
+        switch_mac='00:00:00:01:ea:f1'
+        parsed_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=10, ip_src=ip_src,
+                      ip_dst=ip_dst, eth_dst=switch_mac, eth_src=host_mac, ip_ttl=33)
+        pkt=str(parsed_pkt)
+        self.dataplane.send(33, pkt)
+
+        #build expect packet
+        next_hop_mac='00:00:00:55:55:55' 
+        switch_mac='00:00:00:01:ea:f1'
+        label = (20, 0, 1, 32)
+        exp_pkt = mpls_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=100, label=[label], 
+               eth_dst=next_hop_mac, eth_src=switch_mac, ip_ttl=32, ip_src=ip_src, ip_dst=ip_dst)
+        pkt=str(exp_pkt)
+        verify_packet(self, pkt, 37)
+
+class TestSpine(base_tests.SimpleDataPlane):
+
+  def runTest(self):
+        ip_src='10.0.0.1'
+        ip_dst='20.0.0.2'
+
+        #build outgoing packet
+        spine_mac='00:00:00:55:55:55'
+        switch_mac='00:00:00:01:ea:f2'
+        leaf1= '00:00:00:01:ea:f1' 
+        label = (20, 0, 1, 32)
+        parsed_pkt = mpls_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=100, label=[label],
+               eth_dst=spine_mac, eth_src=leaf1, ip_ttl=32, ip_src=ip_src, ip_dst=ip_dst)
+        pkt=str(parsed_pkt)
+        self.dataplane.send(33, pkt)
+
+        exp_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=20, ip_src=ip_src,
+                        ip_dst=ip_dst, eth_dst=switch_mac, eth_src=spine_mac, ip_ttl=31)
+        pkt=str(exp_pkt)
+        verify_packet(self, pkt, 37)
+
+class TestLeaf2(base_tests.SimpleDataPlane):
+
+  def runTest(self):
+        host_mac='00:00:00:55:55:55'
+        ip_src='10.0.0.1'
+        ip_dst='20.0.0.3'
+        switch_mac='00:00:00:01:ea:f1'
+        parsed_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=10, ip_src=ip_src,
+                      ip_dst=ip_dst, eth_dst=switch_mac, eth_src=host_mac, ip_ttl=33)
+        pkt=str(parsed_pkt)
+        self.dataplane.send(33, pkt)
+        switch_mac='00:00:00:01:ea:f2'
+        host_mac='00:00:00:12:34:02'
+        exp_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=20, ip_src=ip_src,
+                        ip_dst=ip_dst, eth_dst=host_mac, eth_src=switch_mac, ip_ttl=30)
+        pkt=str(exp_pkt)
+        verify_packet(self, pkt, 37)
+
+
+