Added a few test cases
diff --git a/ofdpa/accton_util.py b/ofdpa/accton_util.py
deleted file mode 100755
index 338ab91..0000000
--- a/ofdpa/accton_util.py
+++ /dev/null
@@ -1,1257 +0,0 @@
-import logging
-
-from oftest import config
-import oftest.base_tests as base_tests
-import ofp
-import time
-from oftest.testutils import *
-
-from ncclient import manager
-import ncclient
-
-OFDPA_GROUP_TYPE_SHIFT=28
-OFDPA_VLAN_ID_SHIFT   =16
-OFDPA_TUNNEL_ID_SHIFT =12
-OFDPA_TUNNEL_SUBTYPE_SHIFT=10
-
-#VLAN_TABLE_FLAGS
-VLAN_TABLE_FLAG_ONLY_UNTAG=1
-VLAN_TABLE_FLAG_ONLY_TAG  =2
-VLAN_TABLE_FLAG_ONLY_BOTH =3
-
-PORT_FLOW_TABLE=0
-VLAN_FLOW_TABLE=10
-TERMINATION_FLOW_TABLE=20
-UCAST_ROUTING_FLOW_TABLE=30
-MCAST_ROUTING_FLOW_TABLE=40
-BRIDGE_FLOW_TABLE=50
-ACL_FLOW_TABLE=60
-
-def convertIP4toStr(ip_addr):
-    a=(ip_addr&0xff000000)>>24
-    b=(ip_addr&0x00ff0000)>>16
-    c=(ip_addr&0x0000ff00)>>8
-    d=(ip_addr&0x000000ff)
-    return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
-
-def convertMACtoStr(mac):
-    if not isinstance(mac, list):
-        assert(0)
-
-    return ':'.join(['%02X' % x for x in mac])
-
-def getSwitchCpuMACFromDPID(dpid):
-    str_datapath_id_f= "{:016x}".format(dpid)
-    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
-    switch_cpu_mac_str=str_datapath_id[6:]
-    switch_cpu_mac = switch_cpu_mac_str.split(":")
-    switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
-
-    return switch_cpu_mac_str, switch_cpu_mac
-        
-def DumpGroup(stats, verify_group_stats, always_show=True):
-    if(len(stats) > len(verify_group_stats)):
-        min_len = len(verify_group_stats)
-        print "Stats Len is not the same, stats>verify_group_stats"
-    if(len(stats)< len(verify_group_stats)):
-        min_len = len(stats)    
-        print "Stats Len is not the same, stats<verify_group_stats"
-    else:   
-        min_len = len(stats)
-
-    print "\r\n"
-    for i in range(min_len):
-        gs = stats[i]
-        gv = verify_group_stats[i]        
-        print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify    :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
-        if(len(gs.buckets) != len(gv.buckets)):
-            print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
-
-        for j in range(len(gs.buckets)):
-           b1=gs.buckets[j]
-           b2=gv.buckets[j]           
-           if(len(b1.actions) != len(b2.actions)):
-               print "action len is not the same"
-
-           for k in range(len(b1.actions)):
-               a1=b1.actions[k]
-               a2=b2.actions[k]
-               if(always_show == True):
-                   print "a1:"+a1.show()
-                   print "a2:"+a2.show()               
-
-def AssertGroup(self, stats, verify_group_stats):
-    self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
-
-    for i in range(len(stats)):
-        gs = stats[i]
-        gv = verify_group_stats[i]        
-        self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
-
-        for j in range(len(gs.buckets)):
-           b1=gs.buckets[j]
-           b2=gv.buckets[j]           
-           self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
-
-           for k in range(len(b1.actions)):
-               a1=b1.actions[k]
-               a2=b2.actions[k]
-               self.assertEquals(a1, a2, "action is not the same")
-    
-def encode_l2_interface_group_id(vlan, id):
-    return id + (vlan << OFDPA_VLAN_ID_SHIFT)
-
-def encode_l2_rewrite_group_id(id):
-    return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
-
-def encode_l3_unicast_group_id(id):
-    return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
-
-def encode_l2_mcast_group_id(vlan, id):
-    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
-
-def encode_l2_flood_group_id(vlan, id):
-    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
-    
-def encode_l3_interface_group_id(id):
-    return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
-
-def encode_l3_mcast_group_id(vlan, id):
-    return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
-
-def encode_l3_ecmp_group_id(id):
-    return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
-
-def encode_l2_overlay_group_id(tunnel_id, subtype, index):
-    tunnel_id=tunnel_id&0xffff #16 bits
-    subtype = subtype&3        #2 bits
-    index = index & 0x3f       #10 bits
-    return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
-
-def add_l2_interface_grouop(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
-    # group table
-    # set up untag groups for each port
-    group_id_list=[]
-    msgs=[]
-    for of_port in ports:
-        # do stuff
-        group_id = encode_l2_interface_group_id(vlan_id, of_port)
-        group_id_list.append(group_id)
-        if is_tagged:
-            actions = [
-                ofp.action.output(of_port),
-            ]        
-        else:
-            actions = [
-                ofp.action.pop_vlan(),
-                ofp.action.output(of_port),
-            ]
-
-        buckets = [
-            ofp.bucket(actions=actions),
-        ]
-
-        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                        group_id=group_id,
-                                        buckets=buckets
-                                       )
-        ctrl.message_send(request)
-        msgs.append(request)
-
-        if send_barrier:
-            do_barrier(ctrl)
- 
-    return group_id_list, msgs
-
-def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
-    # group table
-    # set up untag groups for each port
-    group_id = encode_l2_interface_group_id(vlan_id, port)
-
-    if is_tagged:
-        actions = [
-            ofp.action.output(port),
-        ]        
-    else:
-        actions = [
-            ofp.action.pop_vlan(),
-            ofp.action.output(port),
-        ]
-
-    buckets = [
-        ofp.bucket(actions=actions),
-    ]
-
-    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)
- 
-    return group_id, request
-    
-def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
-    buckets=[]
-    for of_port in ports:
-        group_id = encode_l2_interface_group_id(vlanid, of_port)
-        action=[ofp.action.group(group_id)]
-        buckets.append(ofp.bucket(actions=action))
-
-    group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l2_flood_group(ctrl, ports, vlanid, id):
-    buckets=[]
-    for of_port in ports:
-        group_id = encode_l2_interface_group_id(vlanid, of_port)
-        action=[ofp.action.group(group_id)]
-        buckets.append(ofp.bucket(actions=action))
-
-    group_id =encode_l2_flood_group_id(vlanid, id)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
-    group_id = encode_l2_interface_group_id(vlanid, port)
-
-    action=[]
-    if src_mac is not None:
-        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
-
-    if dst_mac is not None:
-        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
-
-    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
-        
-    action.append(ofp.action.group(group_id))
-    
-    buckets = [ofp.bucket(actions=action)]
-
-    group_id =encode_l2_rewrite_group_id(id)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-    
-def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
-    group_id = encode_l2_interface_group_id(vlanid, port)
-
-    action=[]
-    if src_mac is not None:
-        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
-
-    if dst_mac is not None:
-        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
-
-    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
-        
-    action.append(ofp.action.group(group_id))
-    
-    buckets = [ofp.bucket(actions=action)]
-
-    group_id =encode_l3_unicast_group_id(id)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-    
-def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
-    group_id = encode_l2_interface_group_id(vlanid, port)
-
-    action=[]
-    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
-    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))       
-    action.append(ofp.action.group(group_id))
-    
-    buckets = [ofp.bucket(actions=action)]
-
-    group_id =encode_l3_interface_group_id(id)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
-    buckets=[]
-    for group in l3_ucast_groups:
-        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
-
-    group_id =encode_l3_ecmp_group_id(id)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-        
-def add_l3_mcast_group(ctrl, vid,  mcast_group_id, groups_on_buckets):
-    buckets=[]
-    for group in groups_on_buckets:
-        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
-    
-    group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
-    buckets=[]
-    for port in ports:
-        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
-
-    group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
-    buckets=[]
-    for port in ports:
-        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
-
-    group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
-    buckets=[]
-    for port in ports:
-        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
-
-    group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-
-def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
-    buckets=[]
-    for port in ports:
-        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
-
-    group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
-                                    group_id=group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return request
-	
-def add_port_table_flow(ctrl, is_overlay=True):
-    match = ofp.match()
-
-    if is_overlay == True:
-       match.oxm_list.append(ofp.oxm.in_port(0x10000))
-       NEXT_TABLE=50
-    else:
-       match.oxm_list.append(ofp.oxm.in_port(0))
-       NEXT_TABLE=10       
-
-    request = ofp.message.flow_add(
-		table_id=0,
-		cookie=42,
-		match=match,
-		instructions=[
-		  ofp.instruction.goto_table(NEXT_TABLE)
-		],
-		priority=0)
-    logging.info("Add port table, match port %lx" % 0x10000)
-    ctrl.message_send(request)
-    
-def pop_vlan_flow(ctrl, ports, vlan_id=1):
-    msgs=[]
-    for of_port in ports:
-            match = ofp.match()
-            match.oxm_list.append(ofp.oxm.in_port(of_port))
-            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
-            request = ofp.message.flow_add(
-                table_id=10,
-                cookie=42,
-                match=match,
-                instructions=[
-                  ofp.instruction.apply_actions(
-                    actions=[
-                      ofp.action.pop_vlan()
-                    ]
-                  ),
-                  ofp.instruction.goto_table(11)
-                ],
-                priority=0)
-            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
-            ctrl.message_send(request)
-
-    return msgs    
-
-def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
-    # table 10: vlan
-    # goto to table 20
-    msgs=[]
-    for of_port in ports:
-        if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
-            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)
-            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
-            ctrl.message_send(request)
-            
-        if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
-            match = ofp.match()
-            match.oxm_list.append(ofp.oxm.in_port(of_port))
-            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
-            request = ofp.message.flow_add(
-                table_id=10,
-                cookie=42,
-                match=match,
-                instructions=[
-                  ofp.instruction.apply_actions(
-                    actions=[
-                      ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
-                    ]
-                  ),
-                  ofp.instruction.goto_table(20)
-                ],
-                priority=0)
-            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
-            ctrl.message_send(request)
-            msgs.append(request)
-
-    if send_barrier:
-        do_barrier(ctrl)
-
-    return msgs
-
-def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
-    """it will tag pack as untagged packet wether it has tagg or not"""
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.in_port(in_port))
-    actions=[]
-    if match_vid == None:
-        match.oxm_list.append(ofp.oxm.vlan_vid(0))    
-        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
-        goto_table=20
-    else:
-        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
-        actions.append(ofp.action.push_vlan(0x8100))
-        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))        
-        goto_table=20
-        
-    request = ofp.message.flow_add(
-        table_id=10,
-        cookie=42,
-        match=match,
-        instructions=[
-             ofp.instruction.apply_actions(actions=actions)
-            ,ofp.instruction.goto_table(goto_table)
-        ],
-        priority=0)
-    logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
-    ctrl.message_send(request)   
-    
-    if send_barrier:
-        do_barrier(ctrl)
-
-def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
-    """it st flow allow all vlan tag on this port"""
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.in_port(in_port))
-    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
-    request = ofp.message.flow_add(
-        table_id=10,
-        cookie=42,
-        match=match,
-        instructions=[
-            ofp.instruction.goto_table(20) 
-        ],
-        priority=0)
-    logging.info("Add allow all vlan on port %d " %(in_port))
-    ctrl.message_send(request)    
-
-    
-def add_one_vlan_table_flow(ctrl, of_port, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
-    # table 10: vlan
-    # goto to table 20
-    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
-        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=[]
-        if vrf!=0:
-            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
-            
-        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)
-        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
-        ctrl.message_send(request)
-        
-    if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(of_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(0))
-        
-        actions=[]
-        if vrf!=0:
-            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
-            
-        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+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)
-        logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
-        ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)
-
-    return request
-    
-def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
-    match = ofp.match()
-    priority=1000
-    if dst_mac!=None:
-        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
-        priority=2000
-
-    match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
-
-    request = ofp.message.flow_add(
-            table_id=50,
-            cookie=42,
-            match=match,
-            instructions=[
-                ofp.instruction.write_actions(
-                    actions=[
-                        ofp.action.group(group_id)]),
-                    ofp.instruction.goto_table(60)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=priority)
-
-    logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
-    ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)   
-
-    return request        
-
-def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
-    match = ofp.match()
-    if dst_mac!=None:
-        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
-
-    match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
-    if is_group == True:
-        actions=[ofp.action.group(group_id)]
-    else:
-        actions=[ofp.action.output(group_id)]
-
-    request = ofp.message.flow_add(
-            table_id=50,
-            cookie=42,
-            match=match,
-            instructions=[
-                ofp.instruction.write_actions(
-                    actions=actions),
-                    ofp.instruction.goto_table(60)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000) 
-
-    logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
-    ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)   
-
-    return request        
-    
-def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
-    if dst_mac[0]&0x01 == 0x01:
-       match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
-       goto_table=40
-    else:
-       if in_port!=0:
-           match.oxm_list.append(ofp.oxm.in_port(in_port))
-       match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
-       match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
-       if goto_table == None:
-           goto_table=30
-
-    request = ofp.message.flow_add(
-            table_id=20,
-            cookie=42,
-            match=match,
-            instructions=[
-                    ofp.instruction.goto_table(goto_table)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1) 
-
-    logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
-    ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)   
-
-    return request    
-    
-def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_barrier=False):
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
-    if vrf != 0:
-        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
-    
-    if mask!=0:
-        match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
-    else:
-        match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
-
-
-    request = ofp.message.flow_add(
-            table_id=30,
-            cookie=42,
-            match=match,
-            instructions=[
-                    ofp.instruction.write_actions(
-                        actions=[ofp.action.group(action_group_id)]),
-                    ofp.instruction.goto_table(60)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1) 
-
-    logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
-    ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)   
-
-    return request        
-        
-def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.eth_type(0x0800))
-    match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))    
-    if src_ip_mask!=0:
-        match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
-    else:
-        match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
-        
-    match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
-    
-    request = ofp.message.flow_add(
-            table_id=40,
-            cookie=42,
-            match=match,
-            instructions=[
-                    ofp.instruction.write_actions(
-                        actions=[ofp.action.group(action_group_id)]),
-                    ofp.instruction.goto_table(60)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1) 
-
-    logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
-    ctrl.message_send(request)
-
-    if send_barrier:
-        do_barrier(ctrl)   
-
-    return request            
-
-#dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60
-def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
-    match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
-    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
-    match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
-    
-    request = ofp.message.flow_add(
-            table_id=28,
-            cookie=42,
-            match=match,
-            instructions=[
-                    ofp.instruction.write_actions(
-                        actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
-                                 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
-                                 ofp.action.group(action_group_id)]),
-                    ofp.instruction.goto_table(60)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1) 
-    logging.info("Inserting DNAT flow eth_type %lx, dip %lx, ip_proto %ld, tcp_dst %ld, SetFeild: Dip %lx, tcp_dst %ld, action_gorup=%lx",eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id)
-    ctrl.message_send(request)
-    return request
-
-#dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30
-def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
-    match = ofp.match()
-    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
-    match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
-    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
-    match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
-    
-    request = ofp.message.flow_add(
-            table_id=29,
-            cookie=42,
-            match=match,
-            instructions=[
-                    ofp.instruction.write_actions(
-                        actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
-                                 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
-                    ofp.instruction.goto_table(30)
-                ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1) 
-    logging.info("Inserting DNAT flow eth_type %lx, sip %lx, ip_proto %ld, tcp_src %ld, SetFeild: sip %lx, tcp_src %ld",eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src)
-    ctrl.message_send(request)
-    return request
-    
-def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):  
-    """
-    Command Example:
-    of-agent vtap 10001 ethernet 1/1 vid 1
-    of-agent vtp 10001 vni 10
-    """
-    if vlan != 0:
-        config_vtap_xml="""
-        <config>
-            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-                <id>capable-switch-1</id>
-                <resources>
-                    <port xc:operation="OPERATION">
-                        <resource-id >LPORT</resource-id>     
-                        <features>
-                            <current>
-                              <rate>10Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>      
-                            </current>
-                            <advertised>
-                              <rate>10Gb</rate>
-                              <rate>100Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>
-                            </advertised>    
-                            <supported>
-                              <rate>10Gb</rate>
-                              <rate>100Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>
-                            </supported> 
-                            <advertised-peer>
-                              <rate>10Gb</rate>
-                              <rate>100Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>
-                            </advertised-peer>        
-                        </features>
-                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
-                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
-                            <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
-                            <ofdpa10:vni>VNID</ofdpa10:vni>
-                        </ofdpa10:vtap>
-                    </port> 
-              </resources>
-              <logical-switches>
-                  <switch>
-                    <id>DATAPATH_ID</id>
-                    <datapath-id>DATAPATH_ID</datapath-id>
-                    <resources>
-                      <port xc:operation="OPERATION">LPORT</port>
-                    </resources>
-                  </switch>
-              </logical-switches>
-            </capable-switch>
-          </config>
-        """    
-    else:
-        config_vtap_xml="""
-        <config>
-            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-                <id>capable-switch-1</id>
-                <resources>
-                    <port xc:operation="OPERATION">
-                        <resource-id >LPORT</resource-id>     
-                        <features>
-                            <current>
-                              <rate>10Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>      
-                            </current>
-                            <advertised>
-                              <rate>10Gb</rate>
-                              <rate>100Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>
-                            </advertised>    
-                            <supported>
-                              <rate>10Gb</rate>
-                              <rate>100Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>
-                            </supported> 
-                            <advertised-peer>
-                              <rate>10Gb</rate>
-                              <rate>100Gb</rate>
-                              <medium>fiber</medium>
-                              <pause>symmetric</pause>
-                            </advertised-peer>        
-                        </features>
-                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
-                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
-                            <ofdpa10:vni>VNID</ofdpa10:vni>
-                        </ofdpa10:vtap>
-                    </port> 
-              </resources>
-              <logical-switches>
-                  <switch>
-                    <id>DATAPATH_ID</id>
-                    <datapath-id>DATAPATH_ID</datapath-id>
-                    <resources>
-                      <port xc:operation="OPERATION">LPORT</port>
-                    </resources>
-                  </switch>
-              </logical-switches>
-            </capable-switch>
-          </config>
-        """        
-    str_datapath_id_f= "{:016x}".format(dp_id)        
-    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])	
-    config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)      
-    config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))         
-    config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))       
-    config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))     
-    config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
-    config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
-    return config_vtap_xml
-      
-def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'): 
-    """
-    Command Example:
-    of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
-    of-agent vtp 10001 vni 10    
-    """
-
-    config_vtep_xml="""
-        <config>
-          <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-            <id>capable-switch-1</id>
-            <resources>
-             <port xc:operation="OPERATION">
-               <resource-id>LPORT</resource-id>     
-                 <features>
-                   <current>
-                     <rate>10Gb</rate>
-                     <medium>fiber</medium>
-                     <pause>symmetric</pause>      
-                   </current>
-                   <advertised>
-                     <rate>10Gb</rate>
-                     <rate>100Gb</rate>
-                     <medium>fiber</medium>
-                     <pause>symmetric</pause>
-                   </advertised>    
-                   <supported>
-                     <rate>10Gb</rate>
-                     <rate>100Gb</rate>
-                     <medium>fiber</medium>
-                     <pause>symmetric</pause>
-                   </supported> 
-                   <advertised-peer>
-                     <rate>10Gb</rate>
-                     <rate>100Gb</rate>
-                     <medium>fiber</medium>
-                     <pause>symmetric</pause>
-                   </advertised-peer>        
-                </features>
-			  <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
-				<ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
-				<ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
-				<ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
-				<ofdpa10:vni xc:operation="OPERATION">
-                    <ofdpa10:id>VNID</ofdpa10:id>
-                </ofdpa10:vni>
-				<ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
-				<ofdpa10:ttl>TTL</ofdpa10:ttl>
-			  </ofdpa10:vtep>
-             </port> 
-            </resources>
-            <logical-switches>
-                <switch>
-                  <id>DATAPATH_ID</id>
-                  <datapath-id>DATAPATH_ID</datapath-id>
-                  <resources>
-                    <port xc:operation="OPERATION">LPORT</port>
-                  </resources>
-                </switch>
-            </logical-switches>
-          </capable-switch>
-        </config>  
-    """
-    str_datapath_id_f= "{:016x}".format(dp_id)        
-    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])	
-    config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)      
-    config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
-    config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))            
-    config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))                 
-    config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))                      
-    config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))                           
-    config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))                           
-    config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
-    config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))		
-
-    return config_vtep_xml   
-      
-def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'): 
-    #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
-    config_nexthop_xml="""
-      <config>
-          <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-            <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01"  xc:operation="OPERATION">
-              <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
-              <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
-              <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
-              <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
-            </ofdpa10:next-hop>
-          </of11-config:capable-switch>
-      </config>
-      """
-    config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
-    config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))   
-    config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))   
-    config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))   
-    config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))	
-    return config_nexthop_xml   
-
-def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):  
-    #of-agent vni 10 multicast 224.1.1.1 nexthop 20
-    if mcast_ipv4!=None:    
-        config_vni_xml="""
-          <config>
-              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
-                  <ofdpa10:id>VNID</ofdpa10:id>
-                  <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
-                  <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
-                </ofdpa10:vni>
-              </of11-config:capable-switch>
-          </config>
-          """   
-        config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))   
-        config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))             
-    else:
-        config_vni_xml="""
-          <config>
-              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
-                  <ofdpa10:id>VNID</ofdpa10:id>
-                </ofdpa10:vni>
-              </of11-config:capable-switch>
-          </config>
-          """   
-          
-    config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))            
-    config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))	
-    return config_vni_xml
-	
-def get_featureReplay(self):    
-    req = ofp.message.features_request()
-    res, raw = self.controller.transact(req)
-    self.assertIsNotNone(res, "Did not receive a response from the DUT.")        
-    self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
-                 ("Unexpected packet type %d received in response to "
-                  "OFPT_FEATURES_REQUEST") % res.type)
-    return res		
-	
-def send_edit_config(switch_ip, xml, target='runing'):
-    NETCONF_ACCOUNT="netconfuser"
-    NETCONF_PASSWD="netconfuser"
-    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
-        try:
-            m.edit_config(target='running', 
-                      config=xml, 
-                      default_operation='merge', 
-                      error_option='stop-on-error')
-
-        except Exception as e:
-            logging.info("Fail to set xml %s", xml)
-            return False
-
-	#return m.get_config(source='running').data_xml
-    return True
-
-def send_delete_config(switch_ip, xml, target='runing'):
-    NETCONF_ACCOUNT="netconfuser"
-    NETCONF_PASSWD="netconfuser"
-    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
-        try:
-            m.edit_config(target='running', 
-                      config=xml, 
-                      default_operation='delete', 
-                      error_option='stop-on-error')
-
-        except Exception as e:
-            logging.info("Fail to set xml %s", xml)
-            return False
-
-	#return m.get_config(source='running').data_xml
-    return True
-    
-def get_edit_config(switch_ip, target='runing'):
-    NETCONF_ACCOUNT="netconfuser"
-    NETCONF_PASSWD="netconfuser"
-    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
-	    return m.get_config(source='running').data_xml
-
-
-"""
-MPLS
-"""
-
-OFDPA_MPLS_SUBTYPE_SHIFT=24
-OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1 
-OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
-OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
-OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
-OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
-OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
-OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
-OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
-
-def encode_mpls_interface_group_id(subtype, index):
-    index=index&0x00ffffff
-    assert(subtype==0)
-    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
-
-def encode_mpls_label_group_id(subtype, index):
-    index=index&0x00ffffff
-    assert(subtype <=5 or subtype==0)
-    #1: l2 vpn label
-    #2: l3 vpn label
-    #3: mpls tunnel label 1
-    #4: mpls tunnel lable 2
-    #5: mpls swap label
-    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)         
-
-def encode_mpls_forwarding_group_id(subtype, index):
-    index=index&0x00ffffff
-    assert(subtype==6 or subtype==8 or subtype==10)
-    return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)         
-
-
-def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
-    action=[]
-    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
-    action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
-    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vid)))    
-    action.append(ofp.action.group(ref_gid))
-    
-    buckets = [ofp.bucket(actions=action)]
-
-    mpls_group_id =encode_mpls_interface_group_id(subtype, index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                    group_id=mpls_group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return mpls_group_id, request
-
-def add_mpls_label_group(ctrl, subtype, index, ref_gid, 
-                         lmep_id=-1,
-                         qos_index=-1,
-                         push_l2_header=False,
-                         push_vlan=False,
-                         push_mpls_header=False,
-                         push_cw=False,
-                         set_mpls_label=None,
-                         set_bos=None,
-                         set_tc=None,
-                         set_tc_from_table=False,
-                         cpy_tc_outward=False,
-                         set_ttl=None,
-                         cpy_ttl_outward=False,
-                         oam_lm_tx_count=False,
-                         set_pri_from_table=False
-                         ):
-    """
-    @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
-    """      
-    action=[]
-
-    if push_vlan== True:
-        action.append(ofp.action.push_vlan(0x8100))
-    if push_mpls_header== True:
-        action.append(ofp.action.push_mpls(0x8847))
-    if set_mpls_label != None:
-        action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
-    if set_bos != None:
-        action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
-    if set_tc != None:
-        assert(set_tc_from_table==False)
-        action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
-    if set_ttl != None:
-        action.append(ofp.action.set_mpls_ttl(set_ttl))  
-    if cpy_ttl_outward == True:
-        action.append(ofp.action.copy_ttl_out())  
-    """
-    ofdpa experimenter
-    """    
-    if push_l2_header== True:
-        action.append(ofp.action.ofdpa_push_l2_header())          
-    if set_tc_from_table== True:
-        assert(qos_index>=0)
-        assert(set_tc == None)
-        action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))        
-    if cpy_tc_outward == True:
-        action.append(ofp.action.ofdpa_copy_tc_out())	
-    if oam_lm_tx_count == True:
-        assert(qos_index>=0 and lmep_id>=0)	
-        action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))  
-    if set_pri_from_table == True:
-        assert(qos_index>=0)	
-        action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))  
-    if push_cw == True:
-        action.append(ofp.action.ofdpa_push_cw())
-       
-    action.append(ofp.action.group(ref_gid))    
-    buckets = [ofp.bucket(actions=action)]
-    
-    mpls_group_id = encode_mpls_label_group_id(subtype, index)
-    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
-                                    group_id=mpls_group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    
-    return mpls_group_id, request    
-    
-def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids, 
-                              watch_port=None, 
-							  watch_group=ofp.OFPP_ANY, 
-							  push_vlan=None,
-                              pop_vlan=None,
-                              set_vid=None):
-    assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
-	       or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
-		   or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
-
-    buckets=[]
-    if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
-        group_type = ofp.OFPGT_FF
-        for gid in ref_gids:
-            action=[]
-            action.append(ofp.action.group(gid)) 
-            buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
-
-    elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
-        group_type = ofp.OFPGT_SELECT
-        for gid in ref_gids:
-            action=[]
-            action.append(ofp.action.group(gid))    
-            buckets.append(ofp.bucket(actions=action))
-
-    elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
-        group_type = ofp.OFPGT_INDIRECT
-        action=[]
-        if set_vid!=None:
-            action.append(ofp.action.set_field(ofp.oxm.vlan_vid(set_vid)))
-        if push_vlan!=None:
-            action.append(ofp.action.push_vlan(push_vlan))		
-        if pop_vlan!=None:
-            action.append(ofp.action.pop_vlan())		
-            action.append(ofp.action.group(ref_gids[0]))    
-            buckets.append(ofp.bucket(actions=action))
-
-    mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
-    request = ofp.message.group_add(group_type=group_type,
-                                    group_id=mpls_group_id,
-                                    buckets=buckets
-                                   )
-    ctrl.message_send(request)
-    return mpls_group_id, request    
-
-
-"""
-dislay
-"""   
-def print_current_table_flow_stat(ctrl, table_id=0xff):
-    stat_req=ofp.message.flow_stats_request()
-    response, pkt = ctrl.transact(stat_req)
-    if response == None:
-        print "no response"
-        return None
-    print len(response.entries)
-    for obj in response.entries:
-        print "match ", obj.match
-        print "cookie", obj.cookie
-        print "priority", obj.priority
-        print "idle_timeout", obj.idle_timeout
-        print "hard_timeout", obj.hard_timeout
-        #obj.actions
-        print "packet count: %lx"%obj.packet_count
diff --git a/ofdpa/onos.py b/ofdpa/onos.py
index e1d63cb..d365be6 100644
--- a/ofdpa/onos.py
+++ b/ofdpa/onos.py
@@ -475,13 +475,82 @@
             #add MPLS L3 VPN group
             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)
+            #ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, [mpls_label_gid])
+            do_barrier(self.controller)
             #add vlan flow table
-            add_one_vlan_table_flow(self.controller, port, vlan_id, vrf=2, flag=VLAN_TABLE_FLAG_ONLY_BOTH)
+            add_one_vlan_table_flow(self.controller, port, 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)
             #add routing flow
             dst_ip = dip + (vlan_id<<8)
-            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_label_gid, vrf=2)
+            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0xffffff00, mpls_label_gid, vrf=2)
+            #add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id, 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)
+
+        do_barrier(self.controller)
+
+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])
+        for in_port in ports:
+            mac_src='00:00:00:22:22:%02X' % in_port
+            ip_src='192.168.%02d.1' % in_port
+            for out_port in ports:
+                if in_port == out_port:
+                     continue
+                ip_dst='192.168.%02d.1' % out_port
+                parsed_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                    eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
+                    ip_dst=ip_dst)
+                pkt=str(parsed_pkt)
+                self.dataplane.send(in_port, pkt)
+                #build expect packet
+                mac_dst='00:00:00:22:22:%02X' % out_port
+                label = (out_port, 0, 1, 32)
+                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 L3VPN_32(base_tests.SimpleDataPlane):
+    """
+            Insert IP packet
+            Receive MPLS packet
+    """
+    def runTest(self):
+        delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
+
+        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
+        index=1
+        ports = config["port_map"].keys()
+        for port in ports:
+            #add l2 interface group
+            vlan_id=port
+            l2_gid, l2_msg = add_one_l2_interface_group(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)
+            #add MPLS L3 VPN group
+            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)
+            #ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, [mpls_label_gid])
+            do_barrier(self.controller)
+            #add vlan flow table
+            add_one_vlan_table_flow(self.controller, port, 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)
+            #add routing flow
+            dst_ip = dip + (vlan_id<<8)
+            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, mpls_gid, vrf=2)
+            #ecmp_msg.group_id, 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)
@@ -538,7 +607,7 @@
             #add L3 ecmp group
             ecmp_msg = add_l3_ecmp_group(self.controller, port, [l3_msg.group_id])
             #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, 0x8847, intf_src_mac, vlan_id, goto_table=24)
             #add routing flow
@@ -573,4 +642,81 @@
                 verify_packet(self, pkt, out_port)
                 verify_no_other_packets(self)
 
+class MPLSBUG(base_tests.SimpleDataPlane):
+
+    def runTest(self):
+        delete_all_flows(self.controller)
+        delete_all_groups(self.controller)
+
+        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
+        index=1
+        ports = config["port_map"].keys()
+        for port in ports:
+            #add l2 interface group
+            vlan_id=port
+            l2_gid, l2_msg = add_one_l2_interface_group(self.controller, port, vlan_id, True, False)
+            dst_mac[5]=vlan_id
+            #add L3 Unicast  group
+            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 termination flow
+            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
+            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, 0, l3_msg.group_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)
+
+        do_barrier(self.controller)
+
+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])
+        for in_port in ports:
+            mac_src='00:00:00:22:22:%02X' % in_port
+            ip_src='192.168.%02d.1' % in_port
+            for out_port in ports:
+                if in_port == out_port:
+                     continue
+                ip_dst='192.168.%02d.1' % out_port
+                switch_mac = "00:00:00:cc:cc:cc"
+                label = (out_port, 0, 1, 32)
+                parsed_pkt = mpls_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=in_port, ip_src=ip_src,
+                             ip_dst=ip_dst, eth_dst=switch_mac, eth_src=mac_src, label=[label])
+                pkt=str(parsed_pkt)
+                self.dataplane.send(in_port, pkt)
+
+                #build expect packet
+                mac_dst='00:00:00:22:22:%02X' % out_port
+                exp_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                    eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=31, ip_src=ip_src, ip_dst=ip_dst)
+                pkt=str(exp_pkt)
+                verify_packet(self, pkt, out_port)
+                verify_no_other_packets(self)
+                
+                parsed_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
+                    eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
+                    ip_dst=ip_dst)
+                pkt=str(parsed_pkt)
+                self.dataplane.send(in_port, pkt)
+                #build expected packet
+                mac_dst='00:00:00:22:22:%02X' % out_port
+                exp_pkt = simple_tcp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
+                                       eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63,
+                                       ip_src=ip_src, ip_dst=ip_dst)
+                pkt=str(exp_pkt)
+                verify_packet(self, pkt, out_port)
+                verify_no_other_packets(self)
+