Initial set of Fabric switch test cases

Change-Id: I86fd2b67d3b773aa496f5ef61f1e1fdf51fd9925
diff --git a/Fabric/Utilities/accton/accton_util.py b/Fabric/Utilities/accton/accton_util.py
new file mode 100755
index 0000000..0f32e76
--- /dev/null
+++ b/Fabric/Utilities/accton/accton_util.py
@@ -0,0 +1,2210 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging
+
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+import time
+from oftest.testutils import *
+from oftest.parse import parse_ipv6
+
+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
+VLAN_TABLE_FLAG_ONLY_STACKED=5
+VLAN_TABLE_FLAG_PRIORITY=6
+VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
+VLAN_TABLE_FLAG_ONLY_POP_VLAN=8
+
+PORT_FLOW_TABLE=0
+VLAN_FLOW_TABLE=10
+VLAN_1_FLOW_TABLE=11
+MPLS_L2_PORT_FLOW_TABLE=13
+MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE=15
+MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE=16
+TERMINATION_FLOW_TABLE=20
+MPLS_TYPE_FLOW_TABLE=29
+UCAST_ROUTING_FLOW_TABLE=30
+MCAST_ROUTING_FLOW_TABLE=40
+BRIDGE_FLOW_TABLE=50
+ACL_FLOW_TABLE=60
+EGRESS_TPID_FLOW_TABLE = 235
+
+ONF_EXPERIMENTER_ID = 0x4F4E4600
+
+EGRESS_VLAN_FLOW_TABLE=210
+EGRESS_VLAN_1_FLOW_TABLE=211
+EGRESS_MAINTENANCE_POINT_FLOW_TABLE=226
+EGRESS_DSCP_TABLE=230
+EGRESS_TPID_TABLE=235
+EGRESS_SOURCE_MAC_LEARNING_TABLE=254
+
+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_unfiltered_group_id(id):
+    return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_loadbal_group_id(id):
+    return id + (12 << 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_unfiltered_group(ctrl, ports, send_barrier=False, allow_vlan_translation=1):
+    # group table
+    # set up untag groups for each port
+    group_id_list=[]
+    msgs=[]
+    for of_port in ports:
+        # do stuff
+        group_id = encode_l2_unfiltered_group_id(of_port)
+        group_id_list.append(group_id)
+        actions = [ofp.action.output(of_port)]
+
+        actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=allow_vlan_translation)))
+        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_unfiltered_group(ctrl, of_port, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id = encode_l2_unfiltered_group_id(of_port)
+    actions = [ofp.action.output(of_port)]
+    actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
+
+    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_interface_group(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_flood_group_with_gids(ctrl, gids, vlanid, id, send_barrier=False):
+    buckets=[]
+    for gid in gids:
+        action=[ofp.action.group(gid)]
+        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)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def mod_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_modify(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(0x1000+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, send_barrier=False, gid=None):
+
+    if (not gid):
+        group_id = encode_l2_interface_group_id(vlanid, port)
+    else:
+        group_id = gid
+
+    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(0x1000+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)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    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(0x1000+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_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
+    buckets=[]
+    for group in l2_unfil_intf_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id=encode_l2_loadbal_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
+                                   group_id=group_id,
+                                   buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def mod_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
+    buckets=[]
+    for group in l2_unfil_intf_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l2_loadbal_group_id(id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
+    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)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def mod_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_modify(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):
+    # table 10: vlan
+    # goto to table 20
+    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(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)
+
+
+    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) or (flag == 4):
+            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(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, 0x1fff))
+            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 (flag == 4) :
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
+            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 del_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))
+            request = ofp.message.flow_delete(
+                table_id=10,
+                cookie=42,
+                match=match,
+                priority=0)
+            logging.info("Del 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_delete(
+                table_id=10,
+                cookie=42,
+                match=match,
+                priority=0)
+            logging.info("Del 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_translation(ctrl, of_port, vlan_id=1, new_vlan_id=-1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # Install a flow for VLAN translation
+    # in VLAN table.
+    # table 10: vlan
+    # goto to table 20
+    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+        if new_vlan_id != -1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_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)
+
+
+def add_one_egress_vlan_table_flow(ctrl, of_port, match_vlan, inner_vlan, outer_vlan):
+
+    # used for translating single to double tagged packets only
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port))
+    match.oxm_list.append(ofp.oxm.exp1ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION, 1))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vlan,0x1fff))
+
+    actions=[]
+    actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan)))
+    actions.append(ofp.action.push_vlan(0x8100))
+    actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan)))
+
+    request = ofp.message.flow_add(
+            table_id=EGRESS_VLAN_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(EGRESS_DSCP_TABLE)
+            ],
+            priority=0)
+
+    ctrl.message_send(request)
+
+    return
+
+def add_one_vlan_table_flow(ctrl, of_port, out_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+
+    # goto to table 20
+    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        if config["switch_type"] != 'xpliant' and 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_masked(0, 0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        # actions.append(ofp.action.push_vlan(0x8100))
+        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 (flag == 4) :
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
+
+        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 tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
+        # This flag is meant to managed stacked vlan packtes
+        # Matches on outer VLAN_ID, set OVID with outer VLAN.
+        # Finally expose inner VLAN_ID with a pop action and
+        # goto VLAN_1_FLOW_TABLE
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        # actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
+        actions.append(ofp.action.pop_vlan())
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=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(VLAN_1_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_PRIORITY) :
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
+            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.action.push_vlan(0x8100),
+                        ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_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)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_table_flow_pw(ctrl, of_port, tunnel_index, new_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
+    # table 10: vlan
+    # goto to table 13
+    if flag == VLAN_TABLE_FLAG_ONLY_TAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
+
+        actions=[]
+        if vlan_id == -1:
+            actions.append(ofp.action.pop_vlan())
+        if new_vlan_id > 1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0000nnnn is for UNI interfaces
+        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid(0))
+
+        actions=[]
+        if vlan_id > 1:
+    #        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+    #        actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0000nnnn is for UNI interfaces
+        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_1_table_flow(ctrl, of_port, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
+
+    # table 11: vlan 1 table
+    # goto to table 20
+    if flag == VLAN_TABLE_FLAG_ONLY_TAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        actions.append(ofp.action.push_vlan(0x8100))
+        if new_outer_vlan_id != -1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
+        else:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_POP_VLAN:
+
+        print("INSTALLIN IN TABLE 11!")
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        actions.append(ofp.action.pop_vlan())
+
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_1_table_flow_pw(ctrl, of_port, tunnel_index, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, cross_connect=False, send_barrier=False):
+
+    # table 11: vlan 1 table
+    # goto to table 13
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(of_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+    match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+    actions=[]
+
+    if cross_connect:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan_id)))
+    actions.append(ofp.action.push_vlan(0x8100))
+    if new_outer_vlan_id != -1:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
+    else:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
+
+    if not cross_connect:
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+    else:
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT)))
+
+    # 0x0000nnnn is for UNI interfaces
+    actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+    request = ofp.message.flow_add(
+        table_id=11,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                 actions=actions
+            ),
+            ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+        ],
+        priority=0)
+    logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+    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=500
+    if dst_mac!=None:
+        priority=1000
+        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+
+    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_ctrl=False, send_barrier=False, priority = 1):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if config["switch_type"] != 'xpliant' and vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    if send_ctrl:
+        instructions.append(ofp.instruction.write_actions(
+                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
+                            max_len=ofp.OFPCML_NO_BUFFER)]))
+    else:
+        instructions.append(ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    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_unicast_blackhole_flow(ctrl, eth_type, dst_ip, mask, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if config["switch_type"] != 'xpliant' and vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    instructions.append(ofp.instruction.clear_actions( ))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting unicast blackhole 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_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, 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))
+
+    match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    if send_ctrl:
+        instructions.append(ofp.instruction.write_actions(
+                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
+                            max_len=ofp.OFPCML_NO_BUFFER)]))
+    else:
+        instructions.append(ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, dec_ttl=False, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+    write_actions = []
+    write_actions.append(ofp.action.group(action_group_id))
+    apply_actions = []
+    apply_actions = [ofp.action.dec_mpls_ttl(),
+               ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
+    if (goto_table != 29):
+            apply_actions.append(ofp.action.set_field(
+                            ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
+            apply_actions.append(ofp.action.copy_ttl_in())
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+
+    apply_actions = []
+    apply_actions.append(ofp.action.group(action_group_id))
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    if (goto_table != 29):
+        apply_actions.append(ofp.action.pop_mpls(ethertype))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(1))
+
+    apply_actions = []
+    write_actions = []
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    write_actions.append(ofp.action.group(action_group_id))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+
+def add_mpls_flow_pw(ctrl, action_group_id, label, ethertype, bos, tunnel_index, goto_table=MPLS_TYPE_FLOW_TABLE, popMPLS=True, popL2=False, of_port=0, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+
+    apply_actions = []
+    write_actions = []
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    if popMPLS == True:
+        apply_actions.append(ofp.action.copy_ttl_in())
+        apply_actions.append(ofp.action.pop_mpls(ethertype))
+    if bos==1 and popL2 == True:
+        apply_actions.append(ofp.action.ofdpa_pop_l2_header())
+        apply_actions.append(ofp.action.ofdpa_pop_cw())
+        apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0002nnnn is for UNI interfaces
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+
+    write_actions.append(ofp.action.group(action_group_id))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting MPLS flow , label %ld", label)
+    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(0x1000 + 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
+
+def add_acl_rule(ctrl, eth_type=None, ip_proto=None, vlan_id=None, send_barrier=False):
+    match = ofp.match()
+    if eth_type:
+        match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if ip_proto:
+        match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    if vlan_id:
+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[
+                ofp.instruction.apply_actions(
+                    actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
+                    ),
+                ],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    output = "Inserting ACL flow: "
+    if eth_type:
+        output += "eth_type {}, ".format(eth_type)
+    if ip_proto:
+        output += "ip_proto {}, ".format(ip_proto)
+    if vlan_id:
+        output += "vlan_id {}".format(vlan_id)
+    logging.info(output)
+
+    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, send_barrier=False, add=True):
+    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(0x1000+vid)))
+    action.append(ofp.action.group(ref_gid))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id =encode_mpls_interface_group_id(subtype, index)
+    if add:
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=mpls_group_id,
+                                        buckets=buckets
+                                       )
+    else:
+        request = ofp.message.group_modify(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=mpls_group_id,
+                                        buckets=buckets
+                                       )
+
+
+    logging.debug("Adding MPLS interface group %02x, src_mac %s , dst_mac %s , vid %d", mpls_group_id, src_mac, dst_mac, vid)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+    return mpls_group_id, request
+
+def add_mpls_tunnel_label_group(
+    ctrl,
+    ref_gid,
+    subtype,
+    index,
+    label,
+    ):
+
+    action=[]
+    action.append(ofp.action.push_mpls(0x8847))
+    action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+    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_swap_label_group(
+    ctrl,
+    ref_gid,
+    subtype,
+    index,
+    label,
+    ):
+
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+    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
+                                   )
+    logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
+    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,
+                         send_barrier=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)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return mpls_group_id, request
+
+def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0, goto=MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE):
+    """
+    Only action is Group, which must indicate one of:
+    MPLS L2 VPN Label or Fast Failover Protection Group.
+    ref_gid contains this information
+    """
+
+    match = ofp.match()
+
+    write_actions = []
+    write_actions.append(ofp.action.group(ref_gid))
+    apply_actions = []
+
+    if goto==MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE:
+        tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
+        match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
+        match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
+        assert(qos_index>=0)
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_QOS_INDEX, value=qos_index)))
+
+        request = ofp.message.flow_add(
+            table_id=MPLS_L2_PORT_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto)
+                    ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+        logging.info("Inserting flow for Pseudowire Initiation %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE)
+        ctrl.message_send(request)
+
+    if goto==ACL_FLOW_TABLE:
+        tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
+        match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
+        match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT))
+        request = ofp.message.flow_add(
+            table_id=MPLS_L2_PORT_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto)
+                    ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+        logging.info("Inserting flow for VLAN Cross Connect %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, ACL_FLOW_TABLE)
+        ctrl.message_send(request)
+
+    return 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(0x1000+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
+
+def add_one_egress_vlan_tpid_table_flow(ctrl, of_port):
+    # Used for changing ethertype of outer vlan header to 0x88a8
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port, ONF_EXPERIMENTER_ID))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT))
+
+    actions = []
+    actions.append(ofp.action.copy_field(
+        12, 0, 0, ['\x80\x00\x0c\x02', ofp.oxm.exp4ByteReg(oxm_field = 1).pack()])) # VLAN_VID, PACKET_REG(1)
+    actions.append(ofp.action.pop_vlan())
+    actions.append(ofp.action.push_vlan(0x88a8))
+    actions.append(ofp.action.copy_field(
+        12, 0, 0, [ofp.oxm.exp4ByteReg(oxm_field = 1).pack(), '\x80\x00\x0c\x02'])) # PACKET_REG(1), VLAN_VID
+
+    request = ofp.message.flow_add(
+        table_id=EGRESS_TPID_FLOW_TABLE,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=actions
+            ),
+        ],
+        priority=0)
+
+    ctrl.message_send(request)
+
+    return
+
+"""
+display
+"""
+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/Fabric/Utilities/accton/acl_flow.py b/Fabric/Utilities/accton/acl_flow.py
new file mode 100755
index 0000000..c055ba1
--- /dev/null
+++ b/Fabric/Utilities/accton/acl_flow.py
@@ -0,0 +1,71 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+

+class NoVlanOnlyAclOutputPort(base_tests.SimpleDataPlane):

+    """

+    In OFDPA, ACL can save the packet it was dropped vlan table

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+        input_port=ports[0]

+        output_port=ports[1]

+        vlan_id = 10

+        dmac = [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a]

+        gid, req_msg = add_one_l2_interface_group(self.controller, port=output_port, vlan_id=vlan_id, is_tagged=True, send_barrier=False)

+        #add ACL flow to output port

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(input_port))

+        match.oxm_list.append(ofp.oxm.eth_dst(dmac))

+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)        

+

+        dmac_str = convertMACtoStr(dmac)

+        #send packet

+        parsed_pkt = simple_tcp_packet(eth_dst=dmac_str, vlan_vid=vlan_id, dl_vlan_enable=True)

+        self.dataplane.send(input_port, str(parsed_pkt))

+        #verify packet

+        verify_packet(self, str(parsed_pkt), output_port)        

+

+        

+        

+        

+        

+        

+        

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/accton/epr.py b/Fabric/Utilities/accton/epr.py
new file mode 100755
index 0000000..c13a3d7
--- /dev/null
+++ b/Fabric/Utilities/accton/epr.py
@@ -0,0 +1,105 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+"""

+This file test case is copied from NTC EPR bug

+"""

+

+class pvidClear(base_tests.SimpleDataPlane):

+    """

+    AOS5700-54X-00620

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+        port1=ports[0]

+        port2=ports[1]

+        

+        vlan_id = 10

+

+        gid_p1, req_msg_p1 = add_one_l2_interface_group(self.controller, port=port1, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+        gid_p2, req_msg_p2 = add_one_l2_interface_group(self.controller, port=port2, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+        #add ACL flow, in port1 out port2

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(port1))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid_p2)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)        

+        #add ACL flow, in port2 out port1

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(port2))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid_p1)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)    

+        

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

+        self.dataplane.send(port1, str(parsed_pkt))

+        verify_no_packet(self, str(parsed_pkt), port2)         

+        self.dataplane.send(port2, str(parsed_pkt))        

+        verify_no_packet(self, str(parsed_pkt), port1)        

+

+        

+        #add vlan flow table

+        add_vlan_table_flow(self.controller, [port1, port2], vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_UNTAG)

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

+        self.dataplane.send(port1, str(parsed_pkt))

+        verify_packet(self, str(parsed_pkt), port2)        

+        self.dataplane.send(port2, str(parsed_pkt))        

+        verify_packet(self, str(parsed_pkt), port1)

+         

+        #remove vlan table flow        

+        del_vlan_table_flow(self.controller, [port1, port2], vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_UNTAG)

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

+        self.dataplane.send(port1, str(parsed_pkt))

+        verify_no_packet(self, str(parsed_pkt), port2)

+        self.dataplane.send(port2, str(parsed_pkt))

+        verify_no_packet(self, str(parsed_pkt), port1)

+        

+        

+        

+            

diff --git a/Fabric/Utilities/accton/flow_test.py b/Fabric/Utilities/accton/flow_test.py
new file mode 100755
index 0000000..348d8ab
--- /dev/null
+++ b/Fabric/Utilities/accton/flow_test.py
@@ -0,0 +1,1040 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Flow Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class L2McastFlow(base_tests.SimpleDataPlane):

+    """

+    Test output function for an exact-match flow

+

+    Add some multicast flows

+    Then, for all ports, verifies that sending a matching packet

+    to a multicast match results in an output to all ports.

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        # table 10: vlan

+        # send to table 20

+        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,  False, False)

+

+        # set up multicast group

+        add_l2_mcast_group(self.controller, config["port_map"].keys(), 1, 1)

+        

+        test_macs = [[0x01, 0x00, 0x5e, 0x0f, 0xff, 0xff]]

+

+        for test_mac in test_macs:

+            group_id = encode_l2_mcast_group_id(1, 1)

+            add_bridge_flow(self.controller, test_mac, 1, group_id, True)

+

+        for test_mac in test_macs:

+            mactest = ':'.join(['%02X' % x for x in test_mac])

+

+            for in_port in ports:

+                # change dest based on port number

+                parsed_pkt = simple_tcp_packet(eth_dst=mactest)

+                pkt = str(parsed_pkt)

+                logging.info("OutputExact test, from port %d to mac %s", in_port, mactest)

+                self.dataplane.send(in_port, pkt)

+

+                for ofport in ports:

+                    if ofport == in_port: #tx port won't rx packet, unless L3 mcast routing

+                        continue

+                    verify_packet(self, pkt, ofport)

+                verify_no_other_packets(self)

+

+class L2UnicastFlow(base_tests.SimpleDataPlane):

+    """

+    Test output function for an exact-match flow

+

+    For each port A, adds a flow directing matching packets to that port.

+    Then, for all other ports B != A, verifies that sending a matching packet

+    to B results in an output to A.

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        # table 10: vlan

+        # send to table 20

+        #add_vlan_table_flow(self.controller, config["port_map"].keys(),1)

+

+        # group table

+        # set up tag groups for each port

+        add_l2_interface_group(self.controller, config["port_map"].keys(), 1, True, 1)

+

+        for port in ports:

+            add_one_vlan_table_flow(self.controller, port, 1)

+            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)

+

+        for out_port in ports:

+            # change dest based on port number

+            mac_dst= '00:12:34:56:78:%02X' % out_port

+

+            for in_port in ports:

+                if in_port == out_port:

+                    continue

+                # change source based on port number to avoid packet-ins from learning     

+                mac_src= '00:12:34:56:79:%02X' % in_port 

+                parsed_pkt = simple_tcp_packet(dl_vlan_enable=True, vlan_vid=1, eth_dst=mac_dst, eth_src=mac_src)

+                pkt = str(parsed_pkt)

+                logging.info("OutputExact test, ports %d to %d", in_port, out_port)

+                self.dataplane.send(in_port, pkt)

+

+                for ofport in ports:

+                    if ofport in [out_port]:

+                        verify_packet(self, pkt, ofport)

+                    else:

+                        verify_no_packet(self, pkt, ofport)

+                        

+                verify_no_other_packets(self)

+

+class L2Flood(base_tests.SimpleDataPlane):

+    """

+    Test L2 unknown unicast flooding and broadcast flood

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        # table 10: vlan

+        # send to table 20

+        add_vlan_table_flow(self.controller, ports, 1)

+

+        # group table

+        # set up untag groups for each port

+        add_l2_interface_grouop(self.controller, ports, 1,  False, 1)

+

+        input_port = ports.pop()

+        flood_ports= ports

+    

+        #no fllod group create, veriy all drop

+        parsed_pkt = simple_tcp_packet(eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        verify_no_other_packets(self)

+        parsed_pkt = simple_tcp_packet(eth_dst='FF:FF:FF:FF:FF:FF')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        verify_no_other_packets(self)        

+        #add flood groupo    

+        msg=add_l2_flood_group(self.controller, flood_ports, 1, 1)

+        add_bridge_flow(self.controller, None, 1, msg.group_id, True)

+        #verify flood 

+        parsed_pkt = simple_tcp_packet(eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        for ofport in flood_ports:

+            verify_packet(self, pkt, ofport)

+

+        verify_no_other_packets(self)

+               

+        for ofport in flood_ports:

+            self.dataplane.send(ofport, pkt)

+            #self won't rx packet

+            verify_no_packet(self, pkt, ofport)

+            #others will rx packet

+            tmp_ports=[]

+            for tmp in flood_ports:

+                if tmp != ofport:

+                    tmp_ports.append(tmp)                

+            verify_packets(self, pkt, tmp_ports)

+            

+        verify_no_other_packets(self)

+

+        parsed_pkt = simple_tcp_packet(eth_dst='FF:FF:FF:FF:FF:FF')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        for ofport in flood_ports:

+            verify_packet(self, pkt, ofport)        

+        

+class PacketInMiss(base_tests.SimpleDataPlane):

+    """

+    Test packet in function for a table-miss flow

+

+    Send a packet to each dataplane port and verify that a packet

+    in message is received from the controller for each

+    

+    NOTE: Verify This case the oft option shall not use --switch-ip

+    """

+

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        parsed_vlan_pkt = simple_tcp_packet(pktlen=104, 

+                      vlan_vid=0x1001, dl_vlan_enable=True)

+        pkt = str(parsed_pkt)

+        vlan_pkt = str(parsed_vlan_pkt)

+        # table 10: vlan

+        # send to table 20

+        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,  False, 1)

+

+        # create match

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1001))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.apply_actions(

+                    actions=[

+                        ofp.action.output(

+                            port=ofp.OFPP_CONTROLLER,

+                            max_len=ofp.OFPCML_NO_BUFFER)]),

+            ],

+            buffer_id=ofp.OFP_NO_BUFFER,

+            priority=1)

+

+        logging.info("Inserting packet in flow to controller")

+        self.controller.message_send(request)

+        do_barrier(self.controller)

+

+        for of_port in config["port_map"].keys():

+            logging.info("PacketInMiss test, port %d", of_port)

+            self.dataplane.send(of_port, pkt)

+

+            #AOS current packet in will not have vlan tag

+            if config["cicada_poject"]:

+                verify_packet_in(self, vlan_pkt, of_port, ofp.OFPR_ACTION)

+            else:

+                verify_packet_in(self, pkt, of_port, ofp.OFPR_ACTION)

+

+            verify_no_other_packets(self)

+

+class PacketOut(base_tests.SimpleDataPlane):

+    """

+    Verify action Flood, ALL, in port

+    """

+

+    def runTest(self):

+        if config["cicada_poject"]:

+            pass

+            

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        parsed_vlan_pkt = simple_tcp_packet(pktlen=104, 

+                      vlan_vid=0x1002, dl_vlan_enable=True)

+                      

+        pkt = str(parsed_pkt)

+        vlan_pkt = str(parsed_vlan_pkt)

+       

+        

+        #packet out flood, untag packet

+        self.controller.message_send(ofp.message.packet_out(in_port=ofp.OFPP_CONTROLLER,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=pkt)) 

+

+        for of_port in config["port_map"].keys():

+            verify_packet(self, pkt, of_port)

+

+        verify_no_other_packets(self)

+

+        #packet out flood, tag packet, because it can't identify vlan has which port

+        #so we do as all action.

+        self.controller.message_send(ofp.message.packet_out(in_port=ofp.OFPP_CONTROLLER,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=vlan_pkt)) 

+

+        for of_port in config["port_map"].keys():

+            verify_packet(self, vlan_pkt, of_port)

+

+        verify_no_other_packets(self)

+

+        #packet out all

+        self.controller.message_send(ofp.message.packet_out(in_port=ofp.OFPP_CONTROLLER,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=pkt)) 

+

+        for of_port in config["port_map"].keys():

+            verify_packet(self, pkt, of_port)

+

+        verify_no_other_packets(self)        

+        

+        #packet out to in port

+        in_port = config["port_map"].keys()[0]

+        self.controller.message_send(ofp.message.packet_out(in_port=in_port,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=in_port)],

+                                                            data=pkt)) 

+

+        verify_packet(self, pkt, in_port)

+        verify_no_other_packets(self)

+

+class L3UcastRoute(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port2(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """

+    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

+        

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        dst_mac=[0x00, 0x00, 0x00, 0x22, 0x22, 0x00]

+        dip=0xc0a80001

+        for port in config["port_map"].keys():

+            #add l2 interface group

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            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 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)            

+            vlan_id += 1

+        

+        do_barrier(self.controller)  

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+        #port 1 to port 2        

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port1_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)

+        #build expect packet

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port2_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')        

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)

+

+        #port 2 to port 1

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port2_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port2, pkt)

+        #build expect packet

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port1_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port1)

+        verify_no_other_packets(self)    

+

+class L3UcastRouteOnSamVLANSamPort(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        port = config["port_map"].keys()[0]

+		

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        port_mac1=[0x00, 0x00, 0x00, 0x22, 0x22, 0x01]

+        port_mac2=[0x00, 0x00, 0x00, 0x22, 0x22, 0x02]

+        port_ip1=0xc0a80101        

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

+        add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+		#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, 0x0800, intf_src_mac, vlan_id)           

+

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=1, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id)            

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=2, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id)            

+ 

+        do_barrier(self.controller)  

+		

+        """send packet to verify"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+

+class L3UcastRouteOnDiffVLANSamPort(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        port = config["port_map"].keys()[0]

+		

+        port_vlan_id1=1

+        port_vlan_id2=2

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        port_mac1=[0x00, 0x00, 0x00, 0x22, 0x22, 0x01]

+        port_mac2=[0x00, 0x00, 0x00, 0x22, 0x22, 0x02]

+        port_ip1=0xc0a80101

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

+        add_one_l2_interface_group(self.controller, port, vlan_id=port_vlan_id1, is_tagged=True, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port, vlan_id=port_vlan_id2, is_tagged=True, send_barrier=False)

+		#add vlan flow table

+        add_one_vlan_table_flow(self.controller, port, port_vlan_id1, flag=VLAN_TABLE_FLAG_ONLY_BOTH)

+        add_one_vlan_table_flow(self.controller, port, port_vlan_id2, flag=VLAN_TABLE_FLAG_ONLY_BOTH)		

+		#add termination flow

+        add_termination_flow(self.controller, port, 0x0800, intf_src_mac, port_vlan_id1)           

+        add_termination_flow(self.controller, port, 0x0800, intf_src_mac, port_vlan_id2)           

+		

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=port_vlan_id2, id=1, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id)            

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=port_vlan_id1, id=2, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id)            

+ 

+        do_barrier(self.controller)  

+		

+        """send packet to verify"""  

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str =convertMACtoStr(intf_src_mac)

+        port_mac1_str= convertMACtoStr(port_mac1)

+        port_mac2_str= convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id1,									   

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id2,									   

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        switch_mac = convertMACtoStr(intf_src_mac)

+        port_mac2_str=convertMACtoStr(port_mac2)

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id2,									   

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id1,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+		

+class L3UcastVrfRouteOnSamVLANSamPort(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, VRF1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan1, VRF1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    Port1(vlan2, VRF2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan2, VRF2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        port = config["port_map"].keys()[0]

+		

+        vrf1=1

+        vrf2=2

+        vrf1_vlan_id=1

+        vrf2_vlan_id=2

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        port_mac1=[0x00, 0x00, 0x00, 0x22, 0x22, 0x01]

+        port_mac2=[0x00, 0x00, 0x00, 0x22, 0x22, 0x02]

+        port_ip1=0xc0a80101        

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

+        add_one_l2_interface_group(self.controller, port, vlan_id=vrf1_vlan_id, is_tagged=True, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port, vlan_id=vrf2_vlan_id, is_tagged=True, send_barrier=False)

+		#add vlan flow table

+        add_one_vlan_table_flow(self.controller, port, vrf1_vlan_id, vrf=vrf1, flag=VLAN_TABLE_FLAG_ONLY_TAG)

+        add_one_vlan_table_flow(self.controller, port, vrf2_vlan_id, vrf=vrf2, flag=VLAN_TABLE_FLAG_ONLY_TAG)

+        

+		#add termination flow

+        add_termination_flow(self.controller, 0, 0x0800, intf_src_mac, vrf1_vlan_id)

+        add_termination_flow(self.controller, 0, 0x0800, intf_src_mac, vrf2_vlan_id)

+        

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf1_vlan_id, id=1, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id, vrf1)

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf2_vlan_id, id=2, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id, vrf2)

+        

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf1_vlan_id, id=3, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id, vrf1)

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf2_vlan_id, id=4, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id, vrf2)

+        

+        do_barrier(self.controller)  

+	

+        """send packet to verify on VRF vrf1"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+       

+		

+        """send packet to verify on VRF vrf2"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)          

+        

+        

+		  

+                

+class L3UcastECMP(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port2(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """

+    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

+        

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        dst_mac=[0x00, 0x00, 0x00, 0x22, 0x22, 0x00]

+        dip=0xc0a80001

+        for port in config["port_map"].keys():

+            #add l2 interface group

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            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)            

+            ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, [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 termination flow

+            add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)           

+            #add unicast routing flow

+            dst_ip = dip + (vlan_id<<8)

+            #ECMP shall have prefix not 32

+            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id)            

+            vlan_id += 1

+        

+        do_barrier(self.controller)  

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+        #port 1 to port 2        

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port1_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)

+        #build expect packet

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port2_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')        

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)

+

+        #port 2 to port 1

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port2_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port2, pkt)

+        #build expect packet

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port1_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port1)

+        verify_no_other_packets(self)    

+

+                

+class L3UcastECMP2(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port2(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    Portn(vlann, 0x00, 0x00, 0x00, 0x22, 0x22, 0x0n, 19.168.n.1)    

+    """

+    

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        if len(config["port_map"]) <3:

+            logging.info("Port count less than 3, can't run this case")

+            return

+        

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        same_dst_mac=[0x00, 0x00, 0x00, 0x22, 0x22, 0x22]

+

+        l3_ucast_gips=[]        

+        tx_port = config["port_map"].keys()[0]        

+        for port in config["port_map"].keys():

+            #add l2 interface group

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            if tx_port != port:            

+                l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=intf_src_mac, dst_mac=same_dst_mac)            

+                l3_ucast_gips.append(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 termination flow

+            add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)           

+            vlan_id += 1

+

+        tx_dip=0x0a0a0a0a

+        tx_sip=0x0b0a0a0a             

+        ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, l3_ucast_gips)            

+        #ECMP shall have prefix not 32

+        add_unicast_routing_flow(self.controller, 0x0800, tx_dip, 0xffffff00, ecmp_msg.group_id)            

+

+        do_barrier(self.controller)          

+

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        packet_src_mac="00:00:33:44:55:66"

+        #from unknown src ip to unknown dst ip, to verify ecmp

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=packet_src_mac,

+                                       ip_ttl=64,

+                                       ip_src=convertIP4toStr(tx_sip),

+                                       ip_dst=convertIP4toStr(tx_dip))

+        self.dataplane.send(tx_port, str(parsed_pkt))

+        #build expect packet

+        dst_mac=':'.join(['%02X' % x for x in same_dst_mac])

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                   eth_dst=dst_mac,

+                                   eth_src=switch_mac,

+                                   ip_ttl=63,

+                                   ip_src=convertIP4toStr(tx_sip),

+                                   ip_dst=convertIP4toStr(tx_dip)) 

+                                       

+        verify_packet(self, exp_pkt, config["port_map"].keys()[2])

+        verify_no_other_packets(self)

+        tx_sip=tx_sip+0x01000000  

+        #from unknown scr ip to unknown dst ip, to verify ecmp

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=packet_src_mac,

+                                       ip_ttl=64,

+                                       ip_src=convertIP4toStr(tx_sip),

+                                       ip_dst=convertIP4toStr(tx_dip))

+        self.dataplane.send(tx_port, str(parsed_pkt))

+        #build expect packet

+        dst_mac=':'.join(['%02X' % x for x in same_dst_mac])

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                   eth_dst=dst_mac,

+                                   eth_src=switch_mac,

+                                   ip_ttl=63,

+                                   ip_src=convertIP4toStr(tx_sip),

+                                   ip_dst=convertIP4toStr(tx_dip)) 

+                                       

+        verify_packet(self, exp_pkt, config["port_map"].keys()[1])

+        verify_no_other_packets(self)

+

+class L3McastRoute1(base_tests.SimpleDataPlane):

+    """

+    Mcast routing, From VLAN 1 to VLAN 2

+    """

+    def runTest(self):          

+        """

+        port1 (vlan 1)-> port 2 (vlan 2)

+        """

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        if len(config["port_map"]) <3:

+            logging.info("Port count less than 2, can't run this case")

+            return

+

+        vlan_id =1

+        port2_out_vlan=2

+        port3_out_vlan=3

+        in_vlan=1 #macast group vid shall use input vlan diffe from l3 interface use output vlan        

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        intf_src_mac_str=':'.join(['%02X' % x for x in intf_src_mac])        

+        dst_mac=[0x01, 0x00, 0x5e, 0x01, 0x01, 0x01]

+        dst_mac_str=':'.join(['%02X' % x for x in dst_mac])

+        port1_mac=[0x00, 0x11, 0x11, 0x11, 0x11, 0x11]

+        port1_mac_str=':'.join(['%02X' % x for x in port1_mac])

+        src_ip=0xc0a80101

+        src_ip_str="192.168.1.1"

+        dst_ip=0xe0010101

+        dst_ip_str="224.1.1.1"

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+        port3=config["port_map"].keys()[2]

+

+        #add l2 interface group

+        for port in config["port_map"].keys():        

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            #add vlan flow table

+            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)            

+            vlan_id +=1            

+

+        #add termination flow

+        add_termination_flow(self.controller, port1, 0x0800, [0x01, 0x00, 0x5e, 0x00, 0x00, 0x00], vlan_id)

+

+        #add l3 interface group

+        port2_ucast_msg=add_l3_interface_group(self.controller, port2, port2_out_vlan, 2, intf_src_mac)

+        port3_ucast_msg=add_l3_interface_group(self.controller, port3, port3_out_vlan, 3, intf_src_mac)        

+        mcat_group_msg=add_l3_mcast_group(self.controller, in_vlan,  2, [port2_ucast_msg.group_id, port3_ucast_msg.group_id])

+        add_mcast4_routing_flow(self.controller, in_vlan, src_ip, 0, dst_ip, mcat_group_msg.group_id)               

+        

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=port1_mac_str,

+                                       ip_ttl=64,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)            

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=intf_src_mac_str,

+                                       ip_ttl=63,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)            

+        verify_packet(self, pkt, port2)

+        verify_packet(self, pkt, port3)        

+        verify_no_other_packets(self)               

+

+class L3McastRoute2(base_tests.SimpleDataPlane):

+    """

+    Mcast routing, but on same vlan (l2mcast)

+    """

+    def runTest(self):          

+        """

+        port1 (vlan 1)-> port 2 (vlan 1)

+        """

+        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

+

+        vlan_id =1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        intf_src_mac_str=':'.join(['%02X' % x for x in intf_src_mac])        

+        dst_mac=[0x01, 0x00, 0x5e, 0x01, 0x01, 0x01]

+        dst_mac_str=':'.join(['%02X' % x for x in dst_mac])

+        port1_mac=[0x00, 0x11, 0x11, 0x11, 0x11, 0x11]

+        port1_mac_str=':'.join(['%02X' % x for x in port1_mac])

+        src_ip=0xc0a80101

+        src_ip_str="192.168.1.1"

+        dst_ip=0xe0010101

+        dst_ip_str="224.1.1.1"

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+

+        

+        #add l2 interface group

+        l2_intf_group_list=[]

+        for port in config["port_map"].keys():

+            if port != port1 and port !=port2:

+                continue

+            l2_intf_gid, msg=add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            l2_intf_group_list.append(l2_intf_gid)

+            #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, port1, 0x0800, [0x01, 0x00, 0x5e, 0x00, 0x00, 0x00], vlan_id)

+

+        #add l3 interface group

+        mcat_group_msg=add_l3_mcast_group(self.controller, vlan_id,  2, l2_intf_group_list)

+        add_mcast4_routing_flow(self.controller, vlan_id, src_ip, 0, dst_ip, mcat_group_msg.group_id)               

+

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=port1_mac_str,

+                                       ip_ttl=64,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)            

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)               

+            

+

+            

diff --git a/Fabric/Utilities/accton/flow_test2.py b/Fabric/Utilities/accton/flow_test2.py
new file mode 100755
index 0000000..cfe1296
--- /dev/null
+++ b/Fabric/Utilities/accton/flow_test2.py
@@ -0,0 +1,74 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Flow Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class qinq(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)   

+        

+        in_port = config["port_map"].keys()[0]

+        out_port=config["port_map"].keys()[1]        

+        out_vlan=10

+        add_vlan_table_flow_pvid(self.controller, in_port, None, out_vlan, False)

+        add_vlan_table_flow_pvid(self.controller, in_port, 1,out_vlan, False)        

+        group_id, msg=add_one_l2_interface_group(self.controller, out_port, out_vlan,  True, False)

+        #add acl 

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(in_port))    

+        request = ofp.message.flow_add(

+                table_id=60,

+                cookie=42,

+                match=match,

+                instructions=[

+                    ofp.instruction.write_actions(

+                        actions=[

+                            ofp.action.group(msg.group_id)])

+                    ],

+                buffer_id=ofp.OFP_NO_BUFFER,

+                priority=1000) 

+        self.controller.message_send(request)  

+     

+        #input untag packet

+

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(in_port, pkt)

+    

+        parsed_pkt = simple_tcp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=10)

+        verify_packet(self, str(parsed_pkt), out_port)

+

+        #input tag packet

+        parsed_pkt = simple_tcp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=1)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(in_port, pkt)

+    

+        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True, out_vlan_vid=10,

+                                                in_dl_vlan_enable=True, in_vlan_vid=1)

+        verify_packet(self, str(parsed_pkt), out_port)

diff --git a/Fabric/Utilities/accton/group_test.py b/Fabric/Utilities/accton/group_test.py
new file mode 100755
index 0000000..67d6fda
--- /dev/null
+++ b/Fabric/Utilities/accton/group_test.py
@@ -0,0 +1,883 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Group table test

+Verify each group table can created correctly

+"""

+from oftest import config

+

+import logging

+import random

+

+from oftest import config

+import oftest

+import oftest.base_tests as base_tests

+import ofp

+

+from oftest.testutils import *

+from accton_util import *

+

+def getkey(type):

+    def byGroupId(stats_entry):

+        return stats_entry.group_id

+        

+    def byGroupType(stats_entry):

+        return stats_entry.group_type

+

+        

+    if type == "group_id":

+        return byGroupId

+    elif type == "group_type":

+        return byGroupType

+    else:

+         assert(0)

+    return byGroupId        

+               

+class L2InterfaceGroupOne(base_tests.SimpleDataPlane):

+    def runTest(self):    

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+

+        group_list1, msg1 = add_one_l2_interface_group(self.controller, config["port_map"].keys()[0], 1,  False, False)

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=[ofp.group_desc_stats_entry(

+                          group_type=msg1.group_type,

+                          group_id=msg1.group_id,

+                          buckets=msg1.buckets)]

+

+        self.maxDiff=None

+

+        self.assertEquals(stats, verify_group_stats)

+

+class L2InterfaceGroup(base_tests.SimpleDataPlane):

+    def runTest(self):    

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)

+        group_list2, msg2 =add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)       

+        

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=[]

+

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets))        

+

+        for msg in msg2:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets))

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+        #self.maxDiff=None        

+        self.assertEquals(stats, verify_group_stats)

+        

+class L2McastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l2_mcast_group(self.controller, config["port_map"].keys(), 1, 1)

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l2_mcast_group(self.controller, config["port_map"].keys(), 2, 2)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))                                   

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+

+

+class L2FloodGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l2_flood_group(self.controller, config["port_map"].keys(), 1, 1)

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l2_flood_group(self.controller, config["port_map"].keys(), 2, 2)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))                                   

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+

+

+class L2RewriteGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l2_rewrite_group(self.controller, config["port_map"].keys()[0], 1, 1, [00,11,22,33,44,55], [00,22,22,22,22,22])

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l2_rewrite_group(self.controller, config["port_map"].keys()[0], 2, 2, [00,11,22,33,44,55], [00,33,33,33,33,33])

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+        

+

+class L3UnicastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x22,0x22,0x22,0x22,0x22])

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x33,0x33,0x33,0x33,0x33])

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)  

+

+

+class L3ECMPGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x22,0x22,0x22,0x22,0x22])

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x33,0x33,0x33,0x33,0x33])

+

+        group_ids=[msg2.group_id, msg4.group_id]

+        

+        msg5=add_l3_ecmp_group(self.controller, 1, group_ids)

+        

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg5.group_type,

+                                  group_id=msg5.group_id,

+                                  buckets=msg5.buckets)

+                                  )

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+

+

+class L3InterfaceGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)               

+        msg2=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x55])

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)                       

+        msg4=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x66])

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+

+

+class L3McastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        # Vlan 3 forward to vlan 3 port 1 and 2

+        # Vlan 3 foward to vlan 1 port 1

+        # Vlan 3 foward to vlan 2 port 1     

+        # Vlan 3 foward to vlan 2 port 2             

+        group_list1_1, msg1 = add_l2_interface_grouop(self.controller, [config["port_map"].keys()[0]], 1,  False, False)               

+        msg2=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x11])

+        group_list1_2, msg3 = add_l2_interface_grouop(self.controller, [config["port_map"].keys()[0]], 2,  False, False)

+        msg4=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x22])

+        group_list2_1, msg5 = add_l2_interface_grouop(self.controller, [config["port_map"].keys()[1]], 2,  False, False)

+        msg6=add_l3_interface_group(self.controller, config["port_map"].keys()[1], 2, 3, [0x00,0x11,0x22,0x33,0x44,0x33])

+        group_list3, msg7 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 3,  False, False)

+        

+        group_actions=[msg2.group_id, msg4.group_id, msg6.group_id]

+        group_actions.extend(group_list3)

+

+        msg8=add_l3_mcast_group(self.controller, 3, 1, group_actions)

+        

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+        for msg in msg5:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg6.group_type,

+                                  group_id=msg6.group_id,

+                                  buckets=msg6.buckets)

+                                  )                                      

+        for msg in msg7:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )                                      

+                                      

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg8.group_type,

+                                  group_id=msg8.group_id,

+                                  buckets=msg8.buckets)

+                                  )  

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+        

+        

+class mpls_intf_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	2. ref l2_flood_group

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, config["port_map"].keys()[0], test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+              

+

+class mpls_l2_vpn_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)        

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=False,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+                   

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats= get_stats(self, ofp.message.group_desc_stats_request())        

+        stats=sorted(stats, key=getkey("group_id"))  

+        #DumpGroup(stats, verify_group_stats)

+        #AssertGroup(self, stats, verify_group_stats)

+        self.assertEquals(stats, verify_group_stats)       

+		

+

+class mpls_tunnel_lable1_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+		

+

+class mpls_tunnel_lable2_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                        

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+		

+class mpls_swap_label_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                                

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_fastfailover(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                                

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )        

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP, 

+                                                             index=1, 

+                                                             ref_gids=[mpls_label_gid], 

+                                                             watch_port=test_port, 

+                                                             watch_group=ofp.OFPP_ANY, 

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=None)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_ecmp(base_tests.SimpleDataPlane):

+    """chip not support to bind flow on trident2 

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        mpls_intf_msgs=[]

+        mpls_intf_gids=[]

+        l2_intf_msgs=[]

+        index=1

+        #ref l2_intf_group

+        for port in config["port_map"].keys():

+            l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, port, test_vid,  False, False)

+            l2_intf_msgs.append(l2_intf_msg)            

+            mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=index)

+            index=index+1

+            mpls_intf_msgs.append(mpls_intf_msg)

+            mpls_intf_gids.append(mpls_intf_gid)

+            

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_ECMP, 

+                                                             index=1, 

+                                                             ref_gids=mpls_intf_gids, 

+                                                             watch_port=None, 

+                                                             watch_group=None,

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=None)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in l2_intf_msgs:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        for msg in mpls_intf_msgs:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_l2tag(base_tests.SimpleDataPlane):

+    """chip not support

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]

+        index=1

+        #ref l2_intf_group        

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG, 

+                                                             index=1, 

+                                                             ref_gids=l2_intf_gid, 

+                                                             watch_port=None, 

+                                                             watch_group=None,

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=1)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+

+        self.assertEquals(stats, verify_group_stats)  
\ No newline at end of file
diff --git a/Fabric/Utilities/accton/nat.py b/Fabric/Utilities/accton/nat.py
new file mode 100755
index 0000000..5557d60
--- /dev/null
+++ b/Fabric/Utilities/accton/nat.py
@@ -0,0 +1,293 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Nat Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class dnat(base_tests.SimpleDataPlane):

+    """

+    [DNAT]

+      DNAT (inbound)

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./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=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=200, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False)           

+        add_termination_flow(self.controller, input_port, 0x0800, [0x00,0x00,0x00,0x00,0x02,0x00], 200, goto_table=28, send_barrier=False)        

+        

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=100, is_tagged=True, send_barrier=False)

+        msg1=add_l3_unicast_group(self.controller, port=output_port, vlanid=100, id=0x3000001, src_mac=[0x00,0x00,0x00,0x00,0x01,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x01,0x01])

+        add_dnat_flow(self.controller, eth_type=0x0800, ip_dst=0x64000001, ip_proto=6, tcp_dst=5000, set_ip_dst=0x0a000001, set_tcp_dst=2000, action_group_id=msg1.group_id)

+

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:02:00",

+                                       eth_src="00:00:00:00:02:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='100.0.0.1',

+                                       tcp_dport=5000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:01:01",

+                                       eth_src="00:00:00:00:01:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+                                       

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+         

+        

+        

+class dnatEcmp(base_tests.SimpleDataPlane):

+    """

+    [DNAT ECMP]

+      DNAT (inbound) with ECMP

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000 [increase SIP]

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+    Output  eth 1/5 DA000005224466, SA000005223355, Tag 2, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000005 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:55,set_field=eth_dst=00:00:05:22:44:66,set_field=vlan_vid=2,group=0x20005    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x23000001 group=any,port=any,weight=0 group=0x23000005    

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    

+    ./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 runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = config["port_map"].keys()

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=200, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False)   

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=100, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x3000001

+        msg1=add_l3_unicast_group(self.controller, port=output_port, vlanid=100, id=0x3000001, src_mac=[0x00,0x00,0x00,0x00,0x01,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x01,0x01])

+        add_one_l2_interface_group(self.controller, port=output_port2, vlan_id=2, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x3000005

+        msg2=add_l3_unicast_group(self.controller, port=output_port2, vlanid=2, id=0x3000005, src_mac=[0x00,0x00,0x05,0x22,0x33,0x55], dst_mac=[0x00,0x00,0x05,0x22,0x44,0x66])

+        ecmp=add_l3_ecmp_group(self.controller, id=0x1000001, l3_ucast_groups=[msg1.group_id, msg2.group_id])

+        add_termination_flow(self.controller, 0, 0x0800, [0x00,0x00,0x00,0x00,0x02,0x00], 200, goto_table=28, send_barrier=False)

+        add_dnat_flow(self.controller, eth_type=0x0800, ip_dst=0x64000001, ip_proto=6, tcp_dst=5000, set_ip_dst=0x0a000001, set_tcp_dst=2000, action_group_id=ecmp.group_id)

+        

+        

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:02:00",

+                                       eth_src="00:00:00:00:02:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='100.0.0.1',

+                                       tcp_dport=5000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:01:01",

+                                       eth_src="00:00:00:00:01:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+        output_pkt2 = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:05:22:44:66",

+                                       eth_src="00:00:05:22:33:55",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 2,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

+        #self.dataplane.send(input_port, str(input_pkt))

+        #verify_packet(self, str(output_pkt2), output_port2)

+        

+class snat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [SNAT ECMP]

+      SNAT (outbound) with ECMP

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828 [increase DIP]

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+    Output  eth 1/5 DA000000000500, SA000000000501, Tag 5, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3   

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000005 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:05:00,set_field=eth_dst=00:00:00:00:05:01,set_field=vlan_vid=5,group=0x50005

+    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x22000002 group=any,port=any,weight=0 group=0x22000005

+    ./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

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+        

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=100, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False)   

+        add_termination_flow(self.controller, 0, 0x0800, [0x00,0x00,0x00,0x00,0x01,0x00], 100, goto_table=29, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=200, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x2000002

+        msg1=add_l3_unicast_group(self.controller, port=output_port, vlanid=200, id=0x2000002, src_mac=[0x00,0x00,0x00,0x00,0x02,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x02,0x01])

+        

+        add_one_l2_interface_group(self.controller, port=output_port2, vlan_id=5, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x2000002

+        msg2=add_l3_unicast_group(self.controller, port=output_port2, vlanid=5, id=0x2000005, src_mac=[0x00,0x00,0x00,0x00,0x05,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x05,0x01])

+

+        ecmp=add_l3_ecmp_group(self.controller, id=0x1000001, l3_ucast_groups=[msg1.group_id, msg2.group_id])

+        add_snat_flow(self.controller, 0x0800, 0x0a000001, 6, 2000, 0x64000001, 5000)

+        add_unicast_routing_flow(self.controller, 0x0800, 0xc8000001, 0xffffff00, ecmp.group_id, vrf=0, send_barrier=False)

+

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:01:00",

+                                       eth_src="00:00:00:00:01:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,

+                                       ip_ttl=64,                                       

+                                       ip_src='10.0.0.1',

+                                       ip_dst="200.0.0.1",

+                                       tcp_sport=2000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:02:01",

+                                       eth_src="00:00:00:00:02:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="100.0.0.1",

+                                       ip_dst='200.0.0.1',

+                                       tcp_sport=5000)

+        output_pkt2 = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:05:01",

+                                       eth_src="00:00:00:00:05:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 5,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="100.0.0.1",

+                                       ip_dst='200.0.0.1',

+                                       tcp_sport=5000)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        #self.dataplane.send(input_port, str(input_pkt))

+        #verify_packet(self, str(output_pkt2), output_port2)

+        

+"""just for verify it can work after nat ecmp"""

+class l3Route(base_tests.SimpleDataPlane):

+    """

+    [L3 unicast route]

+      Do unicast route and output to specified port

+    

+    Inject  eth 1/3 Tag2, SA000000112233, DA7072cf7cf3a3, SIP 192.168.1.100, DIP 192.168.2.2

+    Output  eth 1/1 Tag3, SA 000004223355, DA 000004224466

+    

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=70:72:cf:7c:f3:a3,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=3,group=0x30001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000003 goto:60

+    """

+    def runTest(self):   

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]    

+

+        add_port_table_flow(self.controller, is_overlay=False)

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=2, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False)   

+        add_termination_flow(self.controller, input_port, 0x0800, [0x70, 0x72, 0xcf, 0x7c, 0xf3, 0xa3], 2, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=3, is_tagged=True, send_barrier=False)

+        msg=add_l3_unicast_group(self.controller, port=output_port, vlanid=3, id=3, src_mac=[0x00,0x00,0x04,0x22,0x33,0x55], dst_mac=[0x00,0x00,0x04,0x22,0x44,0x66])

+        add_unicast_routing_flow(self.controller, 0x0800, 0xc0a80202, 0xffffff00, msg.group_id)

+

+        #verify tx/rx packet

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="70:72:cf:7c:f3:a3",

+                                       eth_src="00:00:00:00:02:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 2,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='192.168.2.2')

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:04:22:44:66",

+                                       eth_src="00:00:04:22:33:55",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 3,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='192.168.2.2')        

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)        

+        

+        

+        

+        

+        

+        

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/accton/vxlan_flow_test.py b/Fabric/Utilities/accton/vxlan_flow_test.py
new file mode 100755
index 0000000..b57b98e
--- /dev/null
+++ b/Fabric/Utilities/accton/vxlan_flow_test.py
@@ -0,0 +1,1281 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Flow Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+import oftest.parse as decode

+       

+class VxlanConfigNetconf(base_tests.SimpleDataPlane):

+    """

+    Verify netconf to configure Vxlan port

+	"""

+    def runTest(self):

+        if config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        xml_before=get_edit_config(config["switch_ip"])

+		#get datapath_id from feature message

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                                                  

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, 

+                                          mcast_ipv4=mcast_ipv4, 

+                                          next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport, access_phy_port, access_port_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)            

+            

+        get_edit_config(config["switch_ip"])

+

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

+												vlan=access_port_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, 

+                                          mcast_ipv4=mcast_ipv4, 

+                                          next_hop_id=next_hop_id_mcast, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)            

+

+        xml_after=get_edit_config(config["switch_ip"])

+        #logging.info("xml_before\n %s", xml_before)

+        #logging.info("xml_after\n %s", xml_after)

+        #netopeer may have problem on xml process

+        #assert(xml_before == xml_after)

+        

+class OverlayFloodGroup(base_tests.SimpleDataPlane):

+    """

+	create two lport

+	"""

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+		

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                                                  

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport, access_phy_port, access_port_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add flow over unicast group

+        msg=add_l2_overlay_flood_over_unicast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+        #verify

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#

+		#flood over mcast

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

+												vlan=access_port_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)            

+

+class OverlayMcastGroup(base_tests.SimpleDataPlane):

+    """

+	create two lport

+	"""

+    def runTest(self):

+        if config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+		

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                                                  

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport, access_phy_port, access_port_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add flow over unicast group

+        msg=msg=add_l2_overlay_mcast_over_unicast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+        #verify

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#

+		#flood over mcast

+        msg=add_l2_overlay_mcast_over_mcast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

+												vlan=access_port_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)            

+										        

+class AccessToNetworkDLFMcast(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=config["port_map"].keys()[2]

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #get_edit_config(config["switch_ip"])

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port_phy_port, vlan_id=network_port_vlan)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, network_lport], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:00:11:11:11:11')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #vxlan packet IP header have some parmater decide by HW,

+        #we can easy to check VxLAN IP header

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, network_lport, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+class AccessToNetworkDLFUcast(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=config["port_map"].keys()[2]

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #get_edit_config(config["switch_ip"])

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port_phy_port, vlan_id=network_port_vlan)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_unicast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, network_lport], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:00:11:11:11:11')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #vxlan packet IP header have some parmater decide by HW,

+        #we can easy to check VxLAN IP header

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, network_lport, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+class AccessWithAccessDiffPortVlan(base_tests.SimpleDataPlane):

+   def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        access_port3_vid=3

+        access_phy_port3=config["port_map"].keys()[2]

+        access_lport3=0x10003

+        vnid=10

+        next_hop_id_mcast=1

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        

+        feature_reply=get_featureReplay(self)	

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, access_phy_port3, access_port3_vid);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, access_lport3], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port 2, vid=0, so untag

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:00:11:11:11:11')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #verify packet on access port 3

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt)

+        verify_packet(self, pkt, access_phy_port3) 

+        verify_no_other_packets(self)

+        

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, access_lport2, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)        

+        verify_no_other_packets(self)

+

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0xaa], vnid, access_lport3, False, True)

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port3)

+        verify_no_other_packets(self)

+

+        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid, operation="delete")

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)   

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        

+class AccessWithAccessSamePortDiffVlan(base_tests.SimpleDataPlane):

+   def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=2

+        access_phy_port2= access_phy_port1

+        access_lport2=0x10002

+        access_port3_vid=3

+        access_phy_port3=access_phy_port1

+        access_lport3=0x10003

+        vnid=10

+        next_hop_id_mcast=1

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        

+        feature_reply=get_featureReplay(self)	

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, access_phy_port3, access_port3_vid);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, access_lport3], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port 2, vid=0, so untag

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable = True,

+                                       vlan_vid = access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #verify packet on access port 3

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt)

+        verify_packet(self, pkt, access_phy_port3) 

+        verify_no_other_packets(self)

+        

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, access_lport2, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable = True,

+                                       vlan_vid = access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)        

+        verify_no_other_packets(self)

+

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0xaa], vnid, access_lport3, False, True)

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port3)

+        verify_no_other_packets(self)

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0xbb], vnid, access_lport2, False, True)

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:bb',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:bb',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        verify_no_other_packets(self)        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid, operation="delete")

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)   

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        

+class AccessWithNetwork(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_lport1_mac=[0x00, 0x00, 0x00, 0x77, 0x77, 0x77]

+        access_lport1_mac_str=(":".join(map(str, map(hex, access_lport1_mac)))).replace("0x", "")

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        access_lport2_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x02]

+        access_lport2_mac_str=(":".join(map(str, map(hex, access_lport2_mac)))).replace("0x", "")		

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=config["port_map"].keys()[2]

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+        network_lport_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x03]

+        network_lport_mac_str=(":".join(map(str, map(hex, network_lport_mac)))).replace("0x", "")

+

+

+        

+        feature_reply=get_featureReplay(self)	

+        #get switch CPU mac

+        str_datapath_id_f= "{:016x}".format(feature_reply.datapath_id)        

+        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))]

+

+        #add config vtep/vtap/nexthop/vni        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        #vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+        add_port_table_flow(self.controller, is_overlay=False)

+        

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port_phy_port, vlan_id=network_port_vlan)

+        #add network mac

+        add_overlay_bridge_flow(self.controller, network_lport_mac, vnid, network_lport, False, True)

+        add_overlay_bridge_flow(self.controller, access_lport1_mac, vnid, access_lport1, False, True)

+

+        #add termination table for network port

+        add_termination_flow(self.controller, in_port=network_port_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port_vlan)

+        #add vlan table for network port rx packet class vlan

+        add_one_vlan_table_flow(self.controller, of_port=network_port_phy_port, 

+                                vlan_id=network_port_vlan)

+

+        #tx packet on access lport 1        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst=network_lport_mac_str,

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port	

+        #need find a way to verify vxlan header        

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst=network_lport_mac_str)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+        #tx packet on network lport

+        inner_pkt = simple_udp_packet(pktlen=96, eth_dst=access_lport1_mac_str)

+        vxlan_pkt = simple_vxlan_packet(eth_dst=switch_cpu_mac_str,

+                                        vnid=vnid, 

+                                        ip_dst= network_port_sip, 

+                                        ip_src=network_port_dip,

+                                        inner_payload=inner_pkt)

+        self.dataplane.send(network_port_phy_port, str(vxlan_pkt))

+        #verify

+        inner_pkt = simple_udp_packet(pktlen=100, eth_dst=access_lport1_mac_str,

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        

+        verify_packet(self, inner_pkt, access_phy_port1)

+        verify_no_other_packets(self)

+

+

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+class NetworkToNetwork(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        This case can't work, can't identify it is chip limitation or not

+        """

+        return

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        vnid=10

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"       

+        next_hop_id_mcast=3

+

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+

+        network_port1_phy_port=config["port_map"].keys()[1]

+        network_lport1=0x10003

+        network_port1_vlan=2

+        network_port1_sip="192.168.1.1"

+        network_port1_dip="192.168.2.1"

+        network_port1_next_hop_id=1

+        network_port1_dst_mac="00:00:11:22:22:11"

+        network_lport1_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x33]

+        network_lport1_mac_str=(":".join(map(str, map(hex, network_lport1_mac)))).replace("0x", "")

+        

+        network_port2_phy_port=config["port_map"].keys()[2]

+        network_lport2=0x10004

+        network_port2_vlan=3

+        network_port2_sip="192.168.3.1"

+        network_port2_dip="192.168.4.1"

+        network_port2_next_hop_id=2

+        network_port2_dst_mac="00:00:11:22:22:22"

+        network_lport2_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x44]

+        network_lport2_mac_str=(":".join(map(str, map(hex, network_lport2_mac)))).replace("0x", "")

+        

+        feature_reply=get_featureReplay(self)	

+        #get switch CPU mac

+        str_datapath_id_f= "{:016x}".format(feature_reply.datapath_id)        

+        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))]

+        #config vlxan

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port1_next_hop_id, 

+		                                          dst_mac=network_port1_dst_mac, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", network_port1_next_hop_id, network_port1_dst_mac, network_port1_phy_port, network_port1_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port2_next_hop_id, 

+		                                          dst_mac=network_port2_dst_mac, 

+												  phy_port=network_port2_phy_port, 

+												  vlan=network_port2_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", network_port2_next_hop_id, network_port2_dst_mac, network_port2_phy_port, network_port2_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, network_port1_phy_port, network_port1_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport1, 

+                                                src_ip=network_port1_sip, dst_ip=network_port1_dip,

+                                                next_hop_id=network_port1_next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport1, network_port1_sip, network_port1_dip, network_port1_next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport2, 

+                                                src_ip=network_port2_sip, dst_ip=network_port2_dip,

+                                                next_hop_id=network_port2_next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport2, network_port2_sip, network_port2_dip, network_port2_next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port1_phy_port, vlan_id=network_port1_vlan)

+        add_one_l2_interface_group(self.controller, network_port2_phy_port, vlan_id=network_port2_vlan)

+        #add network mac

+        add_overlay_bridge_flow(self.controller, network_lport1_mac, vnid, network_lport1, False, True)

+        add_overlay_bridge_flow(self.controller, network_lport2_mac, vnid, network_lport2, False, True)

+

+        #add termination table for network port

+        add_termination_flow(self.controller, in_port=network_port1_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port1_vlan)

+        add_termination_flow(self.controller, in_port=network_port2_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port2_vlan)                             

+        #add vlan table for network port rx packet class vlan

+        add_one_vlan_table_flow(self.controller, of_port=network_port1_phy_port, 

+                                vlan_id=network_port1_vlan)        

+        add_one_vlan_table_flow(self.controller, of_port=network_port2_phy_port, 

+                                vlan_id=network_port2_vlan)        

+        

+        #packet tx on network port 1 rx on network port 2

+        inner_pkt = simple_udp_packet(pktlen=96, eth_dst=network_lport2_mac_str)

+        vxlan_pkt = simple_vxlan_packet(eth_dst=switch_cpu_mac_str,

+                                        vnid=vnid, 

+                                        ip_dst= network_port1_sip, 

+                                        ip_src=network_port1_dip,

+                                        inner_payload=inner_pkt)

+        self.dataplane.send(network_port1_phy_port, str(vxlan_pkt))        

+        #verify     

+        verify_packet(self, str(inner_pkt), network_port2_phy_port)

+        verify_no_other_packets(self)

+

+        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)   

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+          

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport1, 

+												src_ip=network_port1_sip, dst_ip=network_port1_dip, 

+												next_hop_id=network_port1_next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport2, 

+												src_ip=network_port2_sip, dst_ip=network_port2_dip, 

+												next_hop_id=network_port2_next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port1_next_hop_id, 

+		                                          dst_mac=network_port1_dst_mac, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port2_next_hop_id, 

+		                                          dst_mac=network_port2_dst_mac, 

+												  phy_port=network_port2_phy_port, 

+												  vlan=network_port2_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        
\ No newline at end of file