# 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_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, 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_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, 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, 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_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)
    logging.info("Inserting MPLS flow , label %ld", label)
    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, send_barrier=False):
    match = ofp.match()
    if eth_type != None:
            match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    if ip_proto != None:
        match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))

    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 ACL flow eth_type %lx, ip_proto %ld", eth_type, ip_proto)
    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):
    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)
    request = ofp.message.group_add(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):
    """
    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))


    write_actions = []
    write_actions.append(ofp.action.group(ref_gid))
    apply_actions = []
    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(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

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
