'''
OFTests for functionality needed from the OLT.
'''

import logging
from __builtin__ import xrange
from oftest import config
import oftest.base_tests as base_tests
import oftest.packet as scapy

import ofp
import time
import copy

from oftest.testutils import *

from IGMP import IGMPv3

# These parameters can be altered from the command line using the -t or --test-params= options.
# Example: -t 'onu_port=129;olt_port=288;device_type=pmc'
#
onu_port    = test_param_get("onu_port", 130)
onu_port2   = test_param_get("onu_port2", 131)
olt_port    = test_param_get("olt_port", 258)
device_type = test_param_get("device_type", "normal") # options: "normal", "pmc", "cpqd"
logging.info("device_type: %s" % device_type)


def double_vlan_udp_packet(pktlen=100,
                           eth_dst='00:01:02:03:04:05',
                           eth_src='00:06:07:08:09:0a',
                           dl_vlan_enable=False,
                           c_vlan_vid=0,
                           c_vlan_pcp=0,
                           s_vlan_vid=0,
                           s_vlan_pcp=0,
                           ip_src='192.168.0.1',
                           ip_dst='192.168.0.2',
                           ip_tos=0,
                           ip_ttl=64,
                           udp_sport=1234,
                           udp_dport=80,
                           ip_ihl=None,
                           ip_options=False,
                           eth_type=0x8100
                           ):
    """
    Return a double vlan tagged dataplane UDP packet
    Supports a few parameters:
    @param len Length of packet in bytes w/o CRC
    @param eth_dst Destination MAC
    @param eth_src Source MAC
    @param dl_vlan_enable True if the packet is with vlan, False otherwise
    @param c_vlan_vid CVLAN ID
    @param c_vlan_pcp CVLAN priority
    @param s_vlan_vid SVLAN ID
    @param s_vlan_pcp SVLAN priority
    @param ip_src IP source
    @param ip_dst IP destination
    @param ip_tos IP ToS
    @param ip_ttl IP TTL
    @param udp_dport UDP destination port
    @param udp_sport UDP source port

    Generates a simple UDP packet. Users shouldn't assume anything about
    this packet other than that it is a valid ethernet/IP/UDP frame.
    """

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    # Note Dot1Q.id is really CFI
    if (dl_vlan_enable):
        pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=eth_type) / \
              scapy.Dot1Q(prio=s_vlan_pcp, vlan=s_vlan_vid) / \
              scapy.Dot1Q(prio=c_vlan_pcp, vlan=c_vlan_vid) / \
              scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl) / \
              scapy.UDP(sport=udp_sport, dport=udp_dport)
    else:
        if not ip_options:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
                scapy.UDP(sport=udp_sport, dport=udp_dport)

        else:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src) / \
                  scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options) / \
                  scapy.UDP(sport=udp_sport, dport=udp_dport)

    pkt = pkt / ("D" * (pktlen - len(pkt)))

    return pkt

def testPacketIn(self, match, parsed_pkt):
    delete_all_flows(self.controller)

    pkt = str(parsed_pkt)

    for of_port in config["port_map"]:
        m = copy.deepcopy(match)
        m.oxm_list.append(ofp.oxm.in_port(of_port))
        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=m,
            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=1000)
        logging.info("Inserting flow sending matching packets to controller")
        self.controller.message_send(request)
        do_barrier(self.controller)

    for of_port in config["port_map"]:
        logging.info("PacketInExact test, port %d", of_port)
        self.dataplane.send(of_port, pkt)
        verify_packet_in(self, pkt, of_port, ofp.OFPR_ACTION)
        verify_packets(self, pkt, [])


def buildIgmp(payload):
    pkt = pkt = IGMPv3.fixup(scapy.Ether() / scapy.IP() / payload)
    if len(pkt) < 60:
        pad_len = 60 - len(pkt)
        pad = scapy.scapy.layers.l2.Padding()
        pad.load = '\x00' * pad_len
        pkt = pkt / pad
    return pkt


class EapolPacketIn(base_tests.SimpleDataPlane):
    """Verify packet-ins are sent for EAPOL packets """

    def runTest(self):
        logging.info("Running EAPOL Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x888e))
        # Use ethertype 0x888e and multicast destination MAC address
        pkt = simple_eth_packet(pktlen=60, eth_dst='01:00:5E:7F:FF:FF', eth_type=0x888e)

        testPacketIn(self, match, pkt)


class ARPPacketIn(base_tests.SimpleDataPlane):
    """Verify packet-ins are sent for ARP packets """

    def runTest(self):
        logging.info("Running ARP Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x0806))

        # Use ethertype 0x0806
        pkt = simple_eth_packet(eth_type=0x0806)

        testPacketIn(self, match, pkt)


class IGMPPacketIn(base_tests.SimpleDataPlane):
    """Verify packet-ins are sent for IGMP packets """

    def runTest(self):
        logging.info("Running IGMP Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x800))
        match.oxm_list.append(ofp.oxm.ip_proto(2))

        pkt = scapy.Ether(dst='01:00:5E:7F:FF:FF', src='00:00:00:00:00:01')/ \
              scapy.IP(src='10.0.0.1', dst='10.0.0.2', ttl=60, tos=0, id=0, proto=2)

        pkt = pkt / ("0" * (100 - len(pkt)))

        testPacketIn(self, match, pkt)


class IGMPQueryPacketOut(base_tests.SimpleDataPlane):
    """Verify sending multicast membership queries down to onu_ports"""

    def runTest(self):
        logging.info("Running IGMP query packet out")

        igmp = IGMPv3()  # by default this is a query
        pkt = buildIgmp(igmp)

        msg = ofp.message.packet_out(
            in_port=ofp.OFPP_CONTROLLER,
            actions=[ofp.action.output(port=onu_port)],
            buffer_id=ofp.OFP_NO_BUFFER,
            data=str(pkt))

        self.controller.message_send(msg)

        rv = self.controller.message_send(msg)
        self.assertTrue(rv == 0, "Error sending put message")
        verify_no_errors(self.controller)

        verify_packet(self, pkt, onu_port)


class TestMeter(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running Meter tests")
        dropMeterBand = ofp.meter_band.drop(rate=640)
        meter_mod = ofp.message.meter_mod(xid=1, command=ofp.OFPMC_ADD, meter_id=1, meters=[dropMeterBand])
        self.controller.message_send(meter_mod)

        time.sleep(1)

        verify_no_errors(self.controller)

        vlan_id = 201
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.output(port=olt_port)]),
                ofp.instruction.meter(meter_id = 1)
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        time.sleep(1)
        verify_no_errors(self.controller)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.output(port=onu_port)]),
                ofp.instruction.meter(meter_id = 1)
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        time.sleep(1)
        verify_no_errors(self.controller)
        do_barrier(self.controller)
        time.sleep(5)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
        # downstream
        # self.dataplane.send(olt_port, str(inPkt))
        # verify_packet(self, inPkt, onu_port)
        # upstream
        # for i in range(1,400):
        #	self.dataplane.send(onu_port, str(inPkt))
        # verify_packet(self, inPkt, olt_port)

        # clean up the test
        meter_mod = ofp.message.meter_mod(xid=2, command=ofp.OFPMC_DELETE, meter_id=1)
        self.controller.message_send(meter_mod)
        time.sleep(1)
        delete_all_flows(self.controller)
        verify_no_errors(self.controller)


class TestDuplicateMeter(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Duplicate Meter Test")
        dropMeterBand = ofp.meter_band.drop(rate=500)
        meter_mod = ofp.message.meter_mod(xid=1, command=ofp.OFPMC_ADD, meter_id=1, meters=[dropMeterBand])
        self.controller.message_send(meter_mod)
        self.controller.message_send(meter_mod)

        time.sleep(1)

        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            if (not e.message == "unexpected error type=12 code=1"):
                raise AssertionError("Incorrect error type: %s" % e.message)


class VlanTest(base_tests.SimpleDataPlane):
    """Verify the switch can push/pop a VLAN tag and forward out a port """

    def runTest(self):
        logging.info("Running push VLAN test")

        vlan_id = 200

        delete_all_flows(self.controller)

        # PUSH
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        if device_type == "cpqd":
            match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_NONE))
            actions = [
                ofp.action.push_vlan(ethertype=0x8100),
                ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id)),
                ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                ofp.action.output(port=olt_port)
            ]
        else:  # pmc, normal
            match.oxm_list.append(ofp.oxm.vlan_vid_masked(value=ofp.OFPVID_PRESENT, value_mask=ofp.OFPVID_PRESENT))
            match.oxm_list.append(ofp.oxm.vlan_pcp(value = 0))
            actions = [
                ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id)),
                ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                ofp.action.output(port=olt_port)
            ]

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[ofp.instruction.apply_actions(actions=actions)],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        logging.info("Inserting flow tagging upstream")
        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # POP
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.pop_vlan(),
                        ofp.action.output(port=onu_port)])],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        logging.info("Inserting flow tagging downstream")
        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        time.sleep(5)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
        outPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True,
                                   vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)

        # Send untagged packet in the ONU port and expect tagged packet out the OLT port
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, outPkt, olt_port)

        # Send untagged packet in the OLT port and expect no packets to come out
        self.dataplane.send(olt_port, str(inPkt))
        verify_packets(self, outPkt, [])

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)
        if device_type == 'pmc':
            outPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
        else:  # "normal", "cpqd""
            outPkt = simple_udp_packet(pktlen=100)

        # Send tagged packet in the OLT port and expect untagged packet out the OLT port
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)

        # Send tagged packet in the ONU port and expect no packets to come out
        self.dataplane.send(onu_port, str(inPkt))
        verify_packets(self, outPkt, [])


def createAllGroupAdd(group_id, ports=[]):
    buckets = []

    for portNum in ports:
        buckets.append(ofp.common.bucket(watch_port=ofp.OFPP_ANY, watch_group=ofp.OFPG_ANY,
                                         actions=[ofp.action.pop_vlan(), ofp.action.output(port=portNum)]))

    group_add = ofp.message.group_add(group_type=ofp.OFPGT_ALL, group_id=group_id, buckets=buckets)

    return group_add


def createAllGroupMod(group_id, ports=[]):
    buckets = []

    for portNum in ports:
        buckets.append(ofp.common.bucket(watch_port=ofp.OFPP_ANY, watch_group=ofp.OFPG_ANY,
                                         actions=[ofp.action.output(port=portNum)]))

    group_mod = ofp.message.group_mod(command=ofp.OFPGC_MODIFY, group_type=ofp.OFPGT_ALL, group_id=group_id,
                                      buckets=buckets)

    return group_mod


class TestGroupAdd(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1

        # output to two ONU
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Remove the group and then readd it.
        group_delete = ofp.message.group_delete(group_id=test_group_id)
        self.controller.message_send(group_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])
        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


        # clean up the test
        group_delete = ofp.message.group_delete(group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupMod(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1

        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Modifying the group
        group_mod = createAllGroupMod(test_group_id, [onu_port2])

        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add a bucket into the group
        group_mod = createAllGroupMod(test_group_id, [onu_port, onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Modifying a non-existing group
        group_mod = createAllGroupMod(777, [onu_port2])

        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        errorExperienced = 0
        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            errorExperienced = 1
            if (not (e.message == "unexpected error type=6 code=8")):
                raise AssertionError("Incorrect error type: %s" % e.message)
        if not errorExperienced:
            raise AssertionError("An error message is expected, but not shown.")


        # clean up the test
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestDuplicateGroup(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add the same group id
        duplicate_group_fail = 0

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            duplicate_group_fail = 1
            if (not e.message == "unexpected error type=6 code=0"):
                raise AssertionError("Incorrect error type: %s" % e.message)
        if not duplicate_group_fail:
            raise AssertionError("Adding duplicate groups didn't raise an error.")

        # clean up the test
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupAndFlow(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | 201))

        flow_pointing_to_group = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)])],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(flow_pointing_to_group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # After letting a flow rule point to the group, test we can do group_mod
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Test we can remove flows and then remove group
        flow_delete = ofp.message.flow_delete(table_id=test_param_get("table", 0))
        self.controller.message_send(flow_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_delete = ofp.message.group_delete(xid=3, group_id=test_group_id)
        self.controller.message_send(group_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add the group and flow back, test it we can first remove group and then remove the flow.
        '''group_add = createAllGroupAdd(test_group_id, ports=[onu_port])
        self.controller.message_send(group_add)

        self.controller.message_send(flow_pointing_to_group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_delete = ofp.message.group_delete(xid = 4, group_id = test_group_id)
        self.controller.message_send(group_delete)'''

        self.controller.message_send(flow_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupForwarding(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running Group datapath forwarding tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        vlan_id = 201

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, [onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0, eth_dst="01:01:11:12:11:12")
        outPkt = inPkt
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)


        # Now put 2 ONU ports in the group and test that the input packet is
        # duplicated out both ports
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port, onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port2)
        verify_packet(self, outPkt, onu_port)
        # verify_packets(self, outPkt, [onu_port,onu_port2])

        # clean up the test
        request = ofp.message.flow_delete(table_id=test_param_get("table", 0))
        self.controller.message_send(request)
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupModForwarding(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running datapath forwarding tests for group mod")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        vlan_id = 201

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0, eth_dst="01:01:11:12:11:12")
        outPkt = inPkt
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, onu_port2)

        # Now remove onu port 1 from the group and test that the input packet is no longer forwarded to onu port 1
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        time.sleep(10)
        self.dataplane.send(olt_port, str(inPkt))
        verify_no_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, onu_port2)

        # Now remove all ports in the group and test that the input packet is no longer forwarded to any port
        group_mod = createAllGroupMod(test_group_id, ports=[])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)
        time.sleep(10)
        self.dataplane.send(olt_port, str(inPkt))
        verify_packets(self, outPkt, [])


class TransparentVlanTest(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running transparent vlan tests")
        delete_all_flows(self.controller)

        vlan_id = 201
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(port=olt_port)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(port=onu_port)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(2)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)

        # upstream
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, inPkt, olt_port)

        # downstream
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, inPkt, onu_port)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

class RemoveRuleTest(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Testing Rule removal")
        delete_all_flows(self.controller)
        processEapolRule(self, onu_port)

        #wait for the rule to settle
        time.sleep(3)

        installDoubleTaggingRules(1, 2, self.controller)

        #wait for the rules to settle
        time.sleep(3)

        stats = get_flow_stats(self, ofp.match())

        self.assertTrue(len(stats) == 5, \
                        "Wrong number of rules reports; reported %s, expected 5\n\n %s" % (len(stats), stats))

        processEapolRule(self, onu_port, install = False)
        time.sleep(3)

        stats = get_flow_stats(self, ofp.match())

        self.assertTrue(len(stats) == 4, \
                        "Wrong number of rules reports; reported %s, expected 4\n\n %s" % (len(stats), stats))

        logging.info(stats)


class MultipleDoubleTaggingForwarding(base_tests.SimpleDataPlane):

    def runTests(self):
        logging.info("Testing multiple Q-in-Q rules")
        pass


class DoubleVlanTest(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Running double vlan tests")
        delete_all_flows(self.controller)

        c_vlan_id = 100
        s_vlan_id = 102

        installDoubleTaggingRules(s_vlan_id, c_vlan_id, self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        # Test packet flows
        testPacketFlow(self, c_vlan_id, s_vlan_id)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestCyclingDoubleVlan(base_tests.SimpleDataPlane):
    """Cycle through vlans and test traffic flow"""

    def runTest(self):
        logging.info("Running cycling vlan test")

        for stag in xrange(2, 4000, 100):
            for ctag in xrange(2, 4000, 100):
                delete_all_flows(self.controller)
                time.sleep(5)
                installDoubleTaggingRules(stag, ctag, self.controller)
                time.sleep(5)
                testPacketFlow(self, ctag, stag)

def processEapolRule(test, in_port, install = True):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(0x888e))
    match.oxm_list.append(ofp.oxm.in_port(in_port))
    if install:
        request = ofp.message.flow_add(
                table_id=test_param_get("table", 0),
                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=1000)
    else:
        request = ofp.message.flow_delete(
                table_id=test_param_get("table", 0),
                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=1000)
    logging.info("%s flow sending matching packets to controller" % "Install" if install else "Remove")
    test.controller.message_send(request)
    do_barrier(test.controller)

def testPacketFlow(test, c_vlan_id, s_vlan_id):

    incorrectTagPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=100, vlan_pcp=1)
    zeroTaggedPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
    untaggedPkt = simple_udp_packet(pktlen=96)

    upstreamDoubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
                                                     c_vlan_vid=c_vlan_id,
                                                     s_vlan_vid=s_vlan_id,
                                                     c_vlan_pcp=0, s_vlan_pcp=0)

    logging.info("Testing s-tag %d, c-tag %d" % (s_vlan_id, c_vlan_id))

    # test upstream untagged packet got double tag at OLT
    test.dataplane.send(onu_port, str(zeroTaggedPkt))
    verify_packet(test, upstreamDoubleTaggedPkt, olt_port)

    # test downstream doubletagged packet got untagged at ONU
    test.dataplane.send(olt_port, str(upstreamDoubleTaggedPkt))
    if device_type == "pmc":
        verify_packet(test, zeroTaggedPkt, onu_port)
    else:
        verify_packet(test, untaggedPkt, onu_port)

    # test upstream doubletagged packet got dropped
    test.dataplane.send(onu_port, str(upstreamDoubleTaggedPkt))
    verify_no_packet(test, upstreamDoubleTaggedPkt, olt_port)

    # test downstream untagged packet got dropped at ONU
    test.dataplane.send(olt_port, str(untaggedPkt))
    verify_no_packet(test, untaggedPkt, onu_port)

    # test upstream icorrectly tagged packet; should get dropped
    test.dataplane.send(onu_port, str(incorrectTagPkt))
    verify_no_packet(test, upstreamDoubleTaggedPkt, olt_port)


def installDoubleTaggingRules(s_vlan_id, c_vlan_id, controller, cookie=42):

    # upstream flow rule
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(onu_port))
    if device_type == "cpqd":
        match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_NONE))
        actions = [
            ofp.action.push_vlan(ethertype=0x8100),
            ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id)),
            ofp.action.set_field(ofp.oxm.vlan_pcp(0))
        ]
    else:  # "pmc", "normal"
        match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_PRESENT))
        match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))
        actions = [
            ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
        ]
    cookie += 1

    # push inner vlan (c-vlan) for upstream
    request = ofp.message.flow_add(
        table_id=test_param_get("table", 0),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(actions=actions),
            ofp.instruction.goto_table(1)],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)

    # push outer vlan (s-vlan) for upstream
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(onu_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
    cookie += 1

    request = ofp.message.flow_add(
        table_id=test_param_get("table", 1),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[
                    ofp.action.push_vlan(ethertype=0x8100),
                    ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id)),
                    ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                    ofp.action.output(port=olt_port)]),
        ],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)
    cookie += 1

    # strip outer vlan (s-vlan) for downstream
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(olt_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id))
    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
    request = ofp.message.flow_add(
        table_id=test_param_get("table", 0),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[ofp.action.pop_vlan()]),
            ofp.instruction.goto_table(1)],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)

    # rewrite inner vlan (c-vlan) to default (0) for downstream
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(olt_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
    cookie += 1

    request = ofp.message.flow_add(
        table_id=test_param_get("table", 1),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[
                    ofp.action.pop_vlan(),
                    ofp.action.output(port=onu_port)])
        ],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)
