import logging

from oftest import config
import oftest.base_tests as base_tests
import ofp
import time
from oftest.testutils import *

from ncclient import manager
import ncclient

OFDPA_GROUP_TYPE_SHIFT=28
OFDPA_VLAN_ID_SHIFT   =16
OFDPA_TUNNEL_ID_SHIFT =12
OFDPA_TUNNEL_SUBTYPE_SHIFT=10

#VLAN_TABLE_FLAGS
VLAN_TABLE_FLAG_ONLY_UNTAG=1
VLAN_TABLE_FLAG_ONLY_TAG  =2
VLAN_TABLE_FLAG_ONLY_BOTH =3
VLAN_TABLE_FLAG_ONLY_STACKED=5
VLAN_TABLE_FLAG_PRIORITY=6
VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7

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

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_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):
    # 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=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)
        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 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):
    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_l3_unicast_group_id(id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
    group_id = encode_l2_interface_group_id(vlanid, port)

    action=[]
    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(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_l3_ecmp_group(ctrl, id, l3_ucast_groups):
    buckets=[]
    for group in l3_ucast_groups:
        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))

    group_id =encode_l3_ecmp_group_id(id)
    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
                                    group_id=group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)
    return request

def 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_vlan_table_flow(ctrl, of_port, out_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
    # table 10: vlan
    # goto to table 20
    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) 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 mpls_type!=None:
            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=mpls_type)))

        #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.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())

        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.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 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, 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=[]
    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)))

    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=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):
    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.ipv4_dst_masked(dst_ip, mask))

    instructions = []
    instructions.append(ofp.instruction.goto_table(60))
    if send_ctrl:
        instructions.append(ofp.instruction.apply_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 %ld",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, 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))
    actions = []
    actions = [ofp.action.dec_mpls_ttl(),
               ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
    if (goto_table == 29):
            actions.append(ofp.action.group(action_group_id))
    else:
            actions.append(ofp.action.set_field(
                            ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
            actions.append(ofp.action.group(action_group_id))
            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=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))

    actions = []
    actions.append(ofp.action.dec_mpls_ttl())
    if popMPLS == True:
        actions.append(ofp.action.copy_ttl_in())
        actions.append(ofp.action.pop_mpls(ethertype))
    if bos==1 and popL2 == True:
        actions.append(ofp.action.ofdpa_pop_l2_header())
        actions.append(ofp.action.ofdpa_pop_cw())
        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
        # 0x0002nnnn is for UNI interfaces
        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
        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.group(action_group_id))

    request = ofp.message.flow_add(
        table_id=24,
        cookie=43,
        match=match,
        instructions=[
        ofp.instruction.apply_actions(actions=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(vlan_id))
    if src_ip_mask!=0:
        match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
    else:
        match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))

    match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))

    request = ofp.message.flow_add(
            table_id=40,
            cookie=42,
            match=match,
            instructions=[
                    ofp.instruction.write_actions(
                        actions=[ofp.action.group(action_group_id)]),
                    ofp.instruction.goto_table(60)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1)

    logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)

    return request

#dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60
def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
    match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))

    request = ofp.message.flow_add(
            table_id=28,
            cookie=42,
            match=match,
            instructions=[
                    ofp.instruction.write_actions(
                        actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
                                 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
                                 ofp.action.group(action_group_id)]),
                    ofp.instruction.goto_table(60)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1)
    logging.info("Inserting DNAT flow eth_type %lx, dip %lx, ip_proto %ld, tcp_dst %ld, SetFeild: Dip %lx, tcp_dst %ld, action_gorup=%lx",eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id)
    ctrl.message_send(request)
    return request

#dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30
def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
    match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))

    request = ofp.message.flow_add(
            table_id=29,
            cookie=42,
            match=match,
            instructions=[
                    ofp.instruction.write_actions(
                        actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
                                 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
                    ofp.instruction.goto_table(30)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1)
    logging.info("Inserting DNAT flow eth_type %lx, sip %lx, ip_proto %ld, tcp_src %ld, SetFeild: sip %lx, tcp_src %ld",eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src)
    ctrl.message_send(request)
    return request

def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
    """
    Command Example:
    of-agent vtap 10001 ethernet 1/1 vid 1
    of-agent vtp 10001 vni 10
    """
    if vlan != 0:
        config_vtap_xml="""
        <config>
            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <id>capable-switch-1</id>
                <resources>
                    <port xc:operation="OPERATION">
                        <resource-id >LPORT</resource-id>
                        <features>
                            <current>
                              <rate>10Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </current>
                            <advertised>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised>
                            <supported>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </supported>
                            <advertised-peer>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised-peer>
                        </features>
                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
                            <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
                            <ofdpa10:vni>VNID</ofdpa10:vni>
                        </ofdpa10:vtap>
                    </port>
              </resources>
              <logical-switches>
                  <switch>
                    <id>DATAPATH_ID</id>
                    <datapath-id>DATAPATH_ID</datapath-id>
                    <resources>
                      <port xc:operation="OPERATION">LPORT</port>
                    </resources>
                  </switch>
              </logical-switches>
            </capable-switch>
          </config>
        """
    else:
        config_vtap_xml="""
        <config>
            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <id>capable-switch-1</id>
                <resources>
                    <port xc:operation="OPERATION">
                        <resource-id >LPORT</resource-id>
                        <features>
                            <current>
                              <rate>10Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </current>
                            <advertised>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised>
                            <supported>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </supported>
                            <advertised-peer>
                              <rate>10Gb</rate>
                              <rate>100Gb</rate>
                              <medium>fiber</medium>
                              <pause>symmetric</pause>
                            </advertised-peer>
                        </features>
                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
                            <ofdpa10:vni>VNID</ofdpa10:vni>
                        </ofdpa10:vtap>
                    </port>
              </resources>
              <logical-switches>
                  <switch>
                    <id>DATAPATH_ID</id>
                    <datapath-id>DATAPATH_ID</datapath-id>
                    <resources>
                      <port xc:operation="OPERATION">LPORT</port>
                    </resources>
                  </switch>
              </logical-switches>
            </capable-switch>
          </config>
        """
    str_datapath_id_f= "{:016x}".format(dp_id)
    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
    config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
    config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
    config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
    config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
    config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
    config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
    return config_vtap_xml

def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
    """
    Command Example:
    of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
    of-agent vtp 10001 vni 10
    """

    config_vtep_xml="""
        <config>
          <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
            <id>capable-switch-1</id>
            <resources>
             <port xc:operation="OPERATION">
               <resource-id>LPORT</resource-id>
                 <features>
                   <current>
                     <rate>10Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </current>
                   <advertised>
                     <rate>10Gb</rate>
                     <rate>100Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </advertised>
                   <supported>
                     <rate>10Gb</rate>
                     <rate>100Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </supported>
                   <advertised-peer>
                     <rate>10Gb</rate>
                     <rate>100Gb</rate>
                     <medium>fiber</medium>
                     <pause>symmetric</pause>
                   </advertised-peer>
                </features>
			  <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
				<ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
				<ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
				<ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
				<ofdpa10:vni xc:operation="OPERATION">
                    <ofdpa10:id>VNID</ofdpa10:id>
                </ofdpa10:vni>
				<ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
				<ofdpa10:ttl>TTL</ofdpa10:ttl>
			  </ofdpa10:vtep>
             </port>
            </resources>
            <logical-switches>
                <switch>
                  <id>DATAPATH_ID</id>
                  <datapath-id>DATAPATH_ID</datapath-id>
                  <resources>
                    <port xc:operation="OPERATION">LPORT</port>
                  </resources>
                </switch>
            </logical-switches>
          </capable-switch>
        </config>
    """
    str_datapath_id_f= "{:016x}".format(dp_id)
    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
    config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
    config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
    config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
    config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
    config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
    config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
    config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
    config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
    config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))

    return config_vtep_xml

def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
    #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
    config_nexthop_xml="""
      <config>
          <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
            <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01"  xc:operation="OPERATION">
              <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
              <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
              <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
              <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
            </ofdpa10:next-hop>
          </of11-config:capable-switch>
      </config>
      """
    config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
    config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
    config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
    config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
    config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
    return config_nexthop_xml

def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
    #of-agent vni 10 multicast 224.1.1.1 nexthop 20
    if mcast_ipv4!=None:
        config_vni_xml="""
          <config>
              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                  <ofdpa10:id>VNID</ofdpa10:id>
                  <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
                  <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
                </ofdpa10:vni>
              </of11-config:capable-switch>
          </config>
          """
        config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
        config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
    else:
        config_vni_xml="""
          <config>
              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
                  <ofdpa10:id>VNID</ofdpa10:id>
                </ofdpa10:vni>
              </of11-config:capable-switch>
          </config>
          """

    config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
    config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
    return config_vni_xml

def get_featureReplay(self):
    req = ofp.message.features_request()
    res, raw = self.controller.transact(req)
    self.assertIsNotNone(res, "Did not receive a response from the DUT.")
    self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
                 ("Unexpected packet type %d received in response to "
                  "OFPT_FEATURES_REQUEST") % res.type)
    return res

def send_edit_config(switch_ip, xml, target='runing'):
    NETCONF_ACCOUNT="netconfuser"
    NETCONF_PASSWD="netconfuser"
    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
        try:
            m.edit_config(target='running',
                      config=xml,
                      default_operation='merge',
                      error_option='stop-on-error')

        except Exception as e:
            logging.info("Fail to set xml %s", xml)
            return False

	#return m.get_config(source='running').data_xml
    return True

def send_delete_config(switch_ip, xml, target='runing'):
    NETCONF_ACCOUNT="netconfuser"
    NETCONF_PASSWD="netconfuser"
    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
        try:
            m.edit_config(target='running',
                      config=xml,
                      default_operation='delete',
                      error_option='stop-on-error')

        except Exception as e:
            logging.info("Fail to set xml %s", xml)
            return False

	#return m.get_config(source='running').data_xml
    return True

def get_edit_config(switch_ip, target='runing'):
    NETCONF_ACCOUNT="netconfuser"
    NETCONF_PASSWD="netconfuser"
    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
	    return m.get_config(source='running').data_xml


"""
MPLS
"""

OFDPA_MPLS_SUBTYPE_SHIFT=24
OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10




def encode_mpls_interface_group_id(subtype, index):
    index=index&0x00ffffff
    assert(subtype==0)
    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)

def encode_mpls_label_group_id(subtype, index):
    index=index&0x00ffffff
    assert(subtype <=5 or subtype==0)
    #1: l2 vpn label
    #2: l3 vpn label
    #3: mpls tunnel label 1
    #4: mpls tunnel lable 2
    #5: mpls swap label
    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)

def encode_mpls_forwarding_group_id(subtype, index):
    index=index&0x00ffffff
    assert(subtype==6 or subtype==8 or subtype==10)
    return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)


def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
    action=[]
    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
    action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
    if vid != 1:
        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)
    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_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
                                   )
    ctrl.message_send(request)

    return mpls_group_id, request

def add_mpls_label_group(ctrl, subtype, index, ref_gid,
                         lmep_id=-1,
                         qos_index=-1,
                         push_l2_header=False,
                         push_vlan=False,
                         push_mpls_header=False,
                         push_cw=False,
                         set_mpls_label=None,
                         set_bos=None,
                         set_tc=None,
                         set_tc_from_table=False,
                         cpy_tc_outward=False,
                         set_ttl=None,
                         cpy_ttl_outward=False,
                         oam_lm_tx_count=False,
                         set_pri_from_table=False
                         ):
    """
    @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
    """
    action=[]

    if push_vlan== True:
        action.append(ofp.action.push_vlan(0x8100))
    if push_mpls_header== True:
        action.append(ofp.action.push_mpls(0x8847))
    if set_mpls_label != None:
        action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
    if set_bos != None:
        action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
    if set_tc != None:
        assert(set_tc_from_table==False)
        action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
    if set_ttl != None:
        action.append(ofp.action.set_mpls_ttl(set_ttl))
    if cpy_ttl_outward == True:
        action.append(ofp.action.copy_ttl_out())
    """
    ofdpa experimenter
    """
    if push_l2_header== True:
        action.append(ofp.action.ofdpa_push_l2_header())
    if set_tc_from_table== True:
        assert(qos_index>=0)
        assert(set_tc == None)
        action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
    if cpy_tc_outward == True:
        action.append(ofp.action.ofdpa_copy_tc_out())
    if oam_lm_tx_count == True:
        assert(qos_index>=0 and lmep_id>=0)
        action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
    if set_pri_from_table == True:
        assert(qos_index>=0)
        action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
    if push_cw == True:
        action.append(ofp.action.ofdpa_push_cw())

    action.append(ofp.action.group(ref_gid))
    buckets = [ofp.bucket(actions=action)]

    mpls_group_id = encode_mpls_label_group_id(subtype, index)
    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
                                    group_id=mpls_group_id,
                                    buckets=buckets
                                   )
    ctrl.message_send(request)

    return mpls_group_id, request

def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0):
    """
    Only action is Group, which must indicate one of:
    MPLS L2 VPN Label or Fast Failover Protection Group.
    ref_gid contains this information
    """
    tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE

    match = ofp.match()
    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))

    action = []
    action.append(ofp.action.group(ref_gid))
    assert(qos_index>=0)
    action.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.write_actions(
                        actions=action
                        ),
                    ofp.instruction.goto_table(MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE)                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1)
    logging.info("Inserting flow %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)
    return request

    return

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


"""
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
