# 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_blackhole_flow(ctrl, eth_type, dst_ip, mask, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    if config["switch_type"] != 'xpliant' and vrf != 0:
        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))

    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))

    instructions = []
    instructions.append(ofp.instruction.goto_table(60))
    instructions.append(ofp.instruction.clear_actions( ))

    request = ofp.message.flow_add(
            table_id=30,
            cookie=42,
            match=match,
            instructions=instructions,
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=priority)

    logging.info("Inserting unicast blackhole routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)

    return request

def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
    if vrf != 0:
        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))

    match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))

    instructions = []
    instructions.append(ofp.instruction.goto_table(60))
    if send_ctrl:
        instructions.append(ofp.instruction.write_actions(
                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
                            max_len=ofp.OFPCML_NO_BUFFER)]))
    else:
        instructions.append(ofp.instruction.write_actions(
                        actions=[ofp.action.group(action_group_id)]))

    request = ofp.message.flow_add(
            table_id=30,
            cookie=42,
            match=match,
            instructions=instructions,
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1)

    logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
    ctrl.message_send(request)

    if send_barrier:
        do_barrier(ctrl)

    return request

def add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, dec_ttl=False, send_barrier=False):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
    match.oxm_list.append(ofp.oxm.mpls_label(label))
    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
    write_actions = []
    write_actions.append(ofp.action.group(action_group_id))
    apply_actions = []
    apply_actions = [ofp.action.dec_mpls_ttl(),
               ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
    if (goto_table != 29):
            apply_actions.append(ofp.action.set_field(
                            ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
            apply_actions.append(ofp.action.copy_ttl_in())

    request = ofp.message.flow_add(
            table_id=24,
            cookie=43,
            match=match,
            instructions=[
                    ofp.instruction.apply_actions(actions=apply_actions),
                    ofp.instruction.write_actions(actions=write_actions),
                    ofp.instruction.goto_table(goto_table)
                ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1)
    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
