#!/usr/bin/env python3
from __future__ import print_function
import binascii
import random
import socket
import unittest
import time
import re

from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, TCP, UDP
from scapy.layers.inet6 import IPv6
from scapy.contrib.lacp import SlowProtocol, LACP

from config import config
from framework import tag_fixme_vpp_workers, tag_fixme_ubuntu2204, tag_fixme_debian11
from framework import is_distro_ubuntu2204, is_distro_debian11
from framework import VppTestCase, VppTestRunner
from framework import tag_run_solo
from vpp_object import VppObject
from vpp_pg_interface import CaptureTimeoutError
from util import ppp
from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_papi.macaddress import mac_ntop
from socket import inet_ntop
from vpp_papi import VppEnum


class VppCFLOW(VppObject):
    """CFLOW object for IPFIX exporter and Flowprobe feature"""

    def __init__(
        self,
        test,
        intf="pg2",
        active=0,
        passive=0,
        timeout=100,
        mtu=1024,
        datapath="l2",
        layer="l2 l3 l4",
        direction="tx",
    ):
        self._test = test
        self._intf = intf
        self._intf_obj = getattr(self._test, intf)
        self._active = active
        if passive == 0 or passive < active:
            self._passive = active + 1
        else:
            self._passive = passive
        self._datapath = datapath  # l2 ip4 ip6
        self._collect = layer  # l2 l3 l4
        self._direction = direction  # rx tx both
        self._timeout = timeout
        self._mtu = mtu
        self._configured = False

    def add_vpp_config(self):
        self.enable_exporter()
        l2_flag = 0
        l3_flag = 0
        l4_flag = 0
        if "l2" in self._collect.lower():
            l2_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
        if "l3" in self._collect.lower():
            l3_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
        if "l4" in self._collect.lower():
            l4_flag = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
        self._test.vapi.flowprobe_set_params(
            record_flags=(l2_flag | l3_flag | l4_flag),
            active_timer=self._active,
            passive_timer=self._passive,
        )
        self.enable_flowprobe_feature()
        self._test.vapi.cli("ipfix flush")
        self._configured = True

    def remove_vpp_config(self):
        self.disable_exporter()
        self.disable_flowprobe_feature()
        self._test.vapi.cli("ipfix flush")
        self._configured = False

    def enable_exporter(self):
        self._test.vapi.set_ipfix_exporter(
            collector_address=self._test.pg0.remote_ip4,
            src_address=self._test.pg0.local_ip4,
            path_mtu=self._mtu,
            template_interval=self._timeout,
        )

    def _enable_disable_flowprobe_feature(self, is_add):
        which_map = {
            "l2": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2,
            "ip4": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4,
            "ip6": VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6,
        }
        direction_map = {
            "rx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
            "tx": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
            "both": VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
        }
        self._test.vapi.flowprobe_interface_add_del(
            is_add=is_add,
            which=which_map[self._datapath],
            direction=direction_map[self._direction],
            sw_if_index=self._intf_obj.sw_if_index,
        )

    def enable_flowprobe_feature(self):
        self._enable_disable_flowprobe_feature(is_add=True)

    def disable_exporter(self):
        self._test.vapi.cli("set ipfix exporter collector 0.0.0.0")

    def disable_flowprobe_feature(self):
        self._enable_disable_flowprobe_feature(is_add=False)

    def object_id(self):
        return "ipfix-collector-%s-%s" % (self._src, self.dst)

    def query_vpp_config(self):
        return self._configured

    def verify_templates(self, decoder=None, timeout=1, count=3):
        templates = []
        self._test.assertIn(count, (1, 2, 3))
        for _ in range(count):
            p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout)
            self._test.assertTrue(p.haslayer(IPFIX))
            if decoder is not None and p.haslayer(Template):
                templates.append(p[Template].templateID)
                decoder.add_template(p.getlayer(Template))
        return templates


class MethodHolder(VppTestCase):
    """Flow-per-packet plugin: test L2, IP4, IP6 reporting"""

    # Test variables
    debug_print = False
    max_number_of_packets = 10
    pkts = []

    @classmethod
    def setUpClass(cls):
        """
        Perform standard class setup (defined by class method setUpClass in
        class VppTestCase) before running the test case, set test case related
        variables and configure VPP.
        """
        super(MethodHolder, cls).setUpClass()
        if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
            cls, "vpp"
        ):
            return
        try:
            # Create pg interfaces
            cls.create_pg_interfaces(range(9))

            # Packet sizes
            cls.pg_if_packet_sizes = [64, 512, 1518, 9018]

            # Create BD with MAC learning and unknown unicast flooding disabled
            # and put interfaces to this BD
            cls.vapi.bridge_domain_add_del_v2(
                bd_id=1, uu_flood=1, learn=1, flood=1, forward=1, is_add=1
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=cls.pg1._sw_if_index, bd_id=1
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=cls.pg2._sw_if_index, bd_id=1
            )

            # Set up all interfaces
            for i in cls.pg_interfaces:
                i.admin_up()

            cls.pg0.config_ip4()
            cls.pg0.configure_ipv4_neighbors()
            cls.collector = cls.pg0

            cls.pg1.config_ip4()
            cls.pg1.resolve_arp()
            cls.pg2.config_ip4()
            cls.pg2.resolve_arp()
            cls.pg3.config_ip4()
            cls.pg3.resolve_arp()
            cls.pg4.config_ip4()
            cls.pg4.resolve_arp()
            cls.pg7.config_ip4()
            cls.pg8.config_ip4()
            cls.pg8.configure_ipv4_neighbors()

            cls.pg5.config_ip6()
            cls.pg5.resolve_ndp()
            cls.pg5.disable_ipv6_ra()
            cls.pg6.config_ip6()
            cls.pg6.resolve_ndp()
            cls.pg6.disable_ipv6_ra()
        except Exception:
            super(MethodHolder, cls).tearDownClass()
            raise

    @classmethod
    def tearDownClass(cls):
        super(MethodHolder, cls).tearDownClass()

    def create_stream(
        self, src_if=None, dst_if=None, packets=None, size=None, ip_ver="v4"
    ):
        """Create a packet stream to tickle the plugin

        :param VppInterface src_if: Source interface for packet stream
        :param VppInterface src_if: Dst interface for packet stream
        """
        if src_if is None:
            src_if = self.pg1
        if dst_if is None:
            dst_if = self.pg2
        self.pkts = []
        if packets is None:
            packets = random.randint(1, self.max_number_of_packets)
        pkt_size = size
        for p in range(0, packets):
            if size is None:
                pkt_size = random.choice(self.pg_if_packet_sizes)
            info = self.create_packet_info(src_if, dst_if)
            payload = self.info_to_payload(info)
            p = Ether(src=src_if.remote_mac, dst=src_if.local_mac)
            if ip_ver == "v4":
                p /= IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
            else:
                p /= IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
            p /= UDP(sport=1234, dport=4321)
            p /= Raw(payload)
            info.data = p.copy()
            self.extend_packet(p, pkt_size)
            self.pkts.append(p)

    def verify_cflow_data(self, decoder, capture, cflow):
        octets = 0
        packets = 0
        for p in capture:
            octets += p[IP].len
            packets += 1
        if cflow.haslayer(Data):
            data = decoder.decode_data_set(cflow.getlayer(Set))
            for record in data:
                self.assertEqual(int(binascii.hexlify(record[1]), 16), octets)
                self.assertEqual(int(binascii.hexlify(record[2]), 16), packets)

    def send_packets(self, src_if=None, dst_if=None):
        if src_if is None:
            src_if = self.pg1
        if dst_if is None:
            dst_if = self.pg2
        self.pg_enable_capture([dst_if])
        src_if.add_stream(self.pkts)
        self.pg_start()
        return dst_if.get_capture(len(self.pkts))

    def verify_cflow_data_detail(
        self, decoder, capture, cflow, data_set={1: "octets", 2: "packets"}, ip_ver="v4"
    ):
        if self.debug_print:
            print(capture[0].show())
        if cflow.haslayer(Data):
            data = decoder.decode_data_set(cflow.getlayer(Set))
            if self.debug_print:
                print(data)
            if ip_ver == "v4":
                ip_layer = capture[0][IP] if capture[0].haslayer(IP) else None
            else:
                ip_layer = capture[0][IPv6] if capture[0].haslayer(IPv6) else None
            if data_set is not None:
                for record in data:
                    # skip flow if ingress/egress interface is 0
                    if int(binascii.hexlify(record[10]), 16) == 0:
                        continue
                    if int(binascii.hexlify(record[14]), 16) == 0:
                        continue

                    for field in data_set:
                        value = data_set[field]
                        if value == "octets":
                            value = ip_layer.len
                            if ip_ver == "v6":
                                value += 40  # ??? is this correct
                        elif value == "packets":
                            value = 1
                        elif value == "src_ip":
                            if ip_ver == "v4":
                                ip = socket.inet_pton(socket.AF_INET, ip_layer.src)
                            else:
                                ip = socket.inet_pton(socket.AF_INET6, ip_layer.src)
                            value = int(binascii.hexlify(ip), 16)
                        elif value == "dst_ip":
                            if ip_ver == "v4":
                                ip = socket.inet_pton(socket.AF_INET, ip_layer.dst)
                            else:
                                ip = socket.inet_pton(socket.AF_INET6, ip_layer.dst)
                            value = int(binascii.hexlify(ip), 16)
                        elif value == "sport":
                            value = int(capture[0][UDP].sport)
                        elif value == "dport":
                            value = int(capture[0][UDP].dport)
                        self.assertEqual(
                            int(binascii.hexlify(record[field]), 16), value
                        )

    def verify_cflow_data_notimer(self, decoder, capture, cflows):
        idx = 0
        for cflow in cflows:
            if cflow.haslayer(Data):
                data = decoder.decode_data_set(cflow.getlayer(Set))
            else:
                raise Exception("No CFLOW data")

            for rec in data:
                p = capture[idx]
                idx += 1
                self.assertEqual(p[IP].len, int(binascii.hexlify(rec[1]), 16))
                self.assertEqual(1, int(binascii.hexlify(rec[2]), 16))
        self.assertEqual(len(capture), idx)

    def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1):
        """wait for CFLOW packet and verify its correctness

        :param timeout: how long to wait

        """
        self.logger.info("IPFIX: Waiting for CFLOW packet")
        # self.logger.debug(self.vapi.ppcli("show flow table"))
        p = collector_intf.wait_for_packet(timeout=timeout)
        self.assertEqual(p[Set].setID, set_id)
        # self.logger.debug(self.vapi.ppcli("show flow table"))
        self.logger.debug(ppp("IPFIX: Got packet:", p))
        return p


@tag_run_solo
@tag_fixme_vpp_workers
@tag_fixme_ubuntu2204
@tag_fixme_debian11
class Flowprobe(MethodHolder):
    """Template verification, timer tests"""

    @classmethod
    def setUpClass(cls):
        super(Flowprobe, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(Flowprobe, cls).tearDownClass()

    def test_0001(self):
        """timer less than template timeout"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self, active=2)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder)

        self.create_stream(packets=1)
        self.send_packets()
        capture = self.pg2.get_capture(1)

        # make sure the one packet we expect actually showed up
        cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
        self.verify_cflow_data(ipfix_decoder, capture, cflow)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")

    def test_0002(self):
        """timer greater than template timeout"""
        self.logger.info("FFP_TEST_START_0002")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self, timeout=3, active=4)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        ipfix.verify_templates()

        self.create_stream(packets=2)
        self.send_packets()
        capture = self.pg2.get_capture(2)

        # next set of template packet should arrive after 20 seconds
        # template packet should arrive within 20 s
        templates = ipfix.verify_templates(ipfix_decoder, timeout=5)

        # make sure the one packet we expect actually showed up
        cflow = self.wait_for_cflow_packet(self.collector, templates[1], 15)
        self.verify_cflow_data(ipfix_decoder, capture, cflow)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0002")

    def test_cflow_packet(self):
        """verify cflow packet fields"""
        self.logger.info("FFP_TEST_START_0000")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self, intf="pg8", datapath="ip4", layer="l2 l3 l4", active=2
        )
        ipfix.add_vpp_config()

        route_9001 = VppIpRoute(
            self,
            "9.0.0.0",
            24,
            [VppRoutePath(self.pg8._remote_hosts[0].ip4, self.pg8.sw_if_index)],
        )
        route_9001.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.pkts = [
            (
                Ether(dst=self.pg7.local_mac, src=self.pg7.remote_mac)
                / IP(src=self.pg7.remote_ip4, dst="9.0.0.100")
                / TCP(sport=1234, dport=4321, flags=80)
                / Raw(b"\xa5" * 100)
            )
        ]

        nowUTC = int(time.time())
        nowUNIX = nowUTC + 2208988800
        self.send_packets(src_if=self.pg7, dst_if=self.pg8)

        cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
        self.collector.get_capture(2)

        if cflow[0].haslayer(IPFIX):
            self.assertEqual(cflow[IPFIX].version, 10)
            self.assertEqual(cflow[IPFIX].observationDomainID, 1)
            self.assertEqual(cflow[IPFIX].sequenceNumber, 0)
            self.assertAlmostEqual(cflow[IPFIX].exportTime, nowUTC, delta=5)
        if cflow.haslayer(Data):
            record = ipfix_decoder.decode_data_set(cflow[0].getlayer(Set))[0]
            # ingress interface
            self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
            # egress interface
            self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
            # direction
            self.assertEqual(int(binascii.hexlify(record[61]), 16), 1)
            # packets
            self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
            # src mac
            self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
            # dst mac
            self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
            flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
            # flow start timestamp
            self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
            flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
            # flow end timestamp
            self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
            # ethernet type
            self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
            # src ip
            self.assertEqual(inet_ntop(socket.AF_INET, record[8]), self.pg7.remote_ip4)
            # dst ip
            self.assertEqual(inet_ntop(socket.AF_INET, record[12]), "9.0.0.100")
            # protocol (TCP)
            self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
            # src port
            self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
            # dst port
            self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
            # tcp flags
            self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0000")

    def test_interface_dump(self):
        """Dump interfaces with IPFIX flow record generation enabled"""
        self.logger.info("FFP_TEST_START_0003")

        # Enable feature for 3 interfaces
        ipfix1 = VppCFLOW(test=self, intf="pg1", datapath="l2", direction="rx")
        ipfix1.add_vpp_config()

        ipfix2 = VppCFLOW(test=self, intf="pg2", datapath="ip4", direction="tx")
        ipfix2.enable_flowprobe_feature()

        ipfix3 = VppCFLOW(test=self, intf="pg3", datapath="ip6", direction="both")
        ipfix3.enable_flowprobe_feature()

        # When request "all", dump should contain all enabled interfaces
        dump = self.vapi.flowprobe_interface_dump()
        self.assertEqual(len(dump), 3)

        # Verify 1st interface
        self.assertEqual(dump[0].sw_if_index, self.pg1.sw_if_index)
        self.assertEqual(
            dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2
        )
        self.assertEqual(
            dump[0].direction,
            VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
        )

        # Verify 2nd interface
        self.assertEqual(dump[1].sw_if_index, self.pg2.sw_if_index)
        self.assertEqual(
            dump[1].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
        )
        self.assertEqual(
            dump[1].direction,
            VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
        )

        # Verify 3rd interface
        self.assertEqual(dump[2].sw_if_index, self.pg3.sw_if_index)
        self.assertEqual(
            dump[2].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6
        )
        self.assertEqual(
            dump[2].direction,
            VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
        )

        # When request 2nd interface, dump should contain only the specified interface
        dump = self.vapi.flowprobe_interface_dump(sw_if_index=self.pg2.sw_if_index)
        self.assertEqual(len(dump), 1)

        # Verify 2nd interface
        self.assertEqual(dump[0].sw_if_index, self.pg2.sw_if_index)
        self.assertEqual(
            dump[0].which, VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4
        )
        self.assertEqual(
            dump[0].direction,
            VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
        )

        # When request 99th interface, dump should be empty
        dump = self.vapi.flowprobe_interface_dump(sw_if_index=99)
        self.assertEqual(len(dump), 0)

        ipfix1.remove_vpp_config()
        ipfix2.remove_vpp_config()
        ipfix3.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0003")

    def test_get_params(self):
        """Get IPFIX flow record generation parameters"""
        self.logger.info("FFP_TEST_START_0004")

        # Enable feature for an interface with custom parameters
        ipfix = VppCFLOW(test=self, active=20, passive=40, layer="l2 l3 l4")
        ipfix.add_vpp_config()

        # Get and verify parameters
        params = self.vapi.flowprobe_get_params()
        self.assertEqual(params.active_timer, 20)
        self.assertEqual(params.passive_timer, 40)
        record_flags = VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2
        record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3
        record_flags |= VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4
        self.assertEqual(params.record_flags, record_flags)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0004")


class DatapathTestsHolder(object):
    """collect information on Ethernet, IP4 and IP6 datapath (no timers)"""

    @classmethod
    def setUpClass(cls):
        super(DatapathTestsHolder, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(DatapathTestsHolder, cls).tearDownClass()

    def test_templatesL2(self):
        """verify template on L2 datapath"""
        self.logger.info("FFP_TEST_START_0000")
        self.pg_enable_capture(self.pg_interfaces)

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, layer="l2", direction=self.direction
        )
        ipfix.add_vpp_config()

        # template packet should arrive immediately
        self.vapi.ipfix_flush()
        ipfix.verify_templates(timeout=3, count=1)
        self.collector.get_capture(1)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0000")

    def test_L2onL2(self):
        """L2 data on L2 datapath"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, layer="l2", direction=self.direction
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(packets=1)
        capture = self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 256: 8, 61: (self.direction == "tx")},
        )
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")

    def test_L3onL2(self):
        """L3 data on L2 datapath"""
        self.logger.info("FFP_TEST_START_0002")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, layer="l3", direction=self.direction
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=2)

        self.create_stream(packets=1)
        capture = self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {
                2: "packets",
                4: 17,
                8: "src_ip",
                12: "dst_ip",
                61: (self.direction == "tx"),
            },
        )

        self.collector.get_capture(3)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0002")

    def test_L23onL2(self):
        """L2/3 data on L2 datapath"""
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, layer="l2 l3", direction=self.direction
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=3)

        # verify IPv4 and IPv6 flows
        for ip_ver in ("v4", "v6"):
            self.create_stream(packets=1, ip_ver=ip_ver)
            capture = self.send_packets()

            # make sure the one packet we expect actually showed up
            self.vapi.ipfix_flush()
            cflow = self.wait_for_cflow_packet(
                self.collector, templates[1 if ip_ver == "v4" else 2]
            )
            src_ip_id = 8 if ip_ver == "v4" else 27
            dst_ip_id = 12 if ip_ver == "v4" else 28
            self.verify_cflow_data_detail(
                ipfix_decoder,
                capture,
                cflow,
                {
                    2: "packets",
                    256: 8 if ip_ver == "v4" else 56710,
                    4: 17,
                    src_ip_id: "src_ip",
                    dst_ip_id: "dst_ip",
                    61: (self.direction == "tx"),
                },
                ip_ver=ip_ver,
            )

        # verify non-IP flow
        self.pkts = [
            (
                Ether(dst=self.pg2.local_mac, src=self.pg1.remote_mac)
                / SlowProtocol()
                / LACP()
            )
        ]
        capture = self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 256: 2440, 61: (self.direction == "tx")},
        )

        self.collector.get_capture(6)

        ipfix.remove_vpp_config()

    def test_L4onL2(self):
        """L4 data on L2 datapath"""
        self.logger.info("FFP_TEST_START_0003")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, layer="l4", direction=self.direction
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=2)

        self.create_stream(packets=1)
        capture = self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
        )

        self.collector.get_capture(3)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0003")

    def test_templatesIp4(self):
        """verify templates on IP4 datapath"""
        self.logger.info("FFP_TEST_START_0000")

        self.pg_enable_capture(self.pg_interfaces)

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, datapath="ip4", direction=self.direction
        )
        ipfix.add_vpp_config()

        # template packet should arrive immediately
        self.vapi.ipfix_flush()
        ipfix.verify_templates(timeout=3, count=1)
        self.collector.get_capture(1)

        ipfix.remove_vpp_config()

        self.logger.info("FFP_TEST_FINISH_0000")

    def test_L2onIP4(self):
        """L2 data on IP4 datapath"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self,
            intf=self.intf2,
            layer="l2",
            datapath="ip4",
            direction=self.direction,
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
        capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 256: 8, 61: (self.direction == "tx")},
        )

        # expected two templates and one cflow packet
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")

    def test_L3onIP4(self):
        """L3 data on IP4 datapath"""
        self.logger.info("FFP_TEST_START_0002")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self,
            intf=self.intf2,
            layer="l3",
            datapath="ip4",
            direction=self.direction,
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
        capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {
                1: "octets",
                2: "packets",
                8: "src_ip",
                12: "dst_ip",
                61: (self.direction == "tx"),
            },
        )

        # expected two templates and one cflow packet
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0002")

    def test_L4onIP4(self):
        """L4 data on IP4 datapath"""
        self.logger.info("FFP_TEST_START_0003")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self,
            intf=self.intf2,
            layer="l4",
            datapath="ip4",
            direction=self.direction,
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=1)
        capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4)

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
        )

        # expected two templates and one cflow packet
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0003")

    def test_templatesIP6(self):
        """verify templates on IP6 datapath"""
        self.logger.info("FFP_TEST_START_0000")
        self.pg_enable_capture(self.pg_interfaces)

        ipfix = VppCFLOW(
            test=self, intf=self.intf1, datapath="ip6", direction=self.direction
        )
        ipfix.add_vpp_config()

        # template packet should arrive immediately
        ipfix.verify_templates(count=1)
        self.collector.get_capture(1)

        ipfix.remove_vpp_config()

        self.logger.info("FFP_TEST_FINISH_0000")

    def test_L2onIP6(self):
        """L2 data on IP6 datapath"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self,
            intf=self.intf3,
            layer="l2",
            datapath="ip6",
            direction=self.direction,
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
        capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 256: 56710, 61: (self.direction == "tx")},
            ip_ver="v6",
        )

        # expected two templates and one cflow packet
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")

    def test_L3onIP6(self):
        """L3 data on IP6 datapath"""
        self.logger.info("FFP_TEST_START_0002")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self,
            intf=self.intf3,
            layer="l3",
            datapath="ip6",
            direction=self.direction,
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
        capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 27: "src_ip", 28: "dst_ip", 61: (self.direction == "tx")},
            ip_ver="v6",
        )

        # expected two templates and one cflow packet
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0002")

    def test_L4onIP6(self):
        """L4 data on IP6 datapath"""
        self.logger.info("FFP_TEST_START_0003")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(
            test=self,
            intf=self.intf3,
            layer="l4",
            datapath="ip6",
            direction=self.direction,
        )
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.create_stream(src_if=self.pg5, dst_if=self.pg6, packets=1, ip_ver="IPv6")
        capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6)

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[0])
        self.verify_cflow_data_detail(
            ipfix_decoder,
            capture,
            cflow,
            {2: "packets", 7: "sport", 11: "dport", 61: (self.direction == "tx")},
            ip_ver="v6",
        )

        # expected two templates and one cflow packet
        self.collector.get_capture(2)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0003")

    def test_0001(self):
        """no timers, one CFLOW packet, 9 Flows inside"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder)

        self.create_stream(packets=9)
        capture = self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        cflow = self.wait_for_cflow_packet(self.collector, templates[1])
        self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow])
        self.collector.get_capture(4)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")

    def test_0002(self):
        """no timers, two CFLOW packets (mtu=260), 3 Flows in each"""
        self.logger.info("FFP_TEST_START_0002")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self, intf=self.intf1, direction=self.direction, mtu=260)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        self.vapi.ipfix_flush()
        templates = ipfix.verify_templates(ipfix_decoder)

        self.create_stream(packets=6)
        capture = self.send_packets()

        # make sure the one packet we expect actually showed up
        cflows = []
        self.vapi.ipfix_flush()
        cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
        cflows.append(self.wait_for_cflow_packet(self.collector, templates[1]))
        self.verify_cflow_data_notimer(ipfix_decoder, capture, cflows)
        self.collector.get_capture(5)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0002")


@tag_fixme_vpp_workers
class DatapathTx(MethodHolder, DatapathTestsHolder):
    """Collect info on Ethernet, IP4 and IP6 datapath (TX) (no timers)"""

    intf1 = "pg2"
    intf2 = "pg4"
    intf3 = "pg6"
    direction = "tx"


@tag_fixme_vpp_workers
class DatapathRx(MethodHolder, DatapathTestsHolder):
    """Collect info on Ethernet, IP4 and IP6 datapath (RX) (no timers)"""

    intf1 = "pg1"
    intf2 = "pg3"
    intf3 = "pg5"
    direction = "rx"


@unittest.skipUnless(config.extended, "part of extended tests")
class DisableIPFIX(MethodHolder):
    """Disable IPFIX"""

    @classmethod
    def setUpClass(cls):
        super(DisableIPFIX, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(DisableIPFIX, cls).tearDownClass()

    def test_0001(self):
        """disable IPFIX after first packets"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder)

        self.create_stream()
        self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        self.wait_for_cflow_packet(self.collector, templates[1])
        self.collector.get_capture(4)

        # disable IPFIX
        ipfix.disable_exporter()
        self.pg_enable_capture([self.collector])

        self.send_packets()

        # make sure no one packet arrived in 1 minute
        self.vapi.ipfix_flush()
        self.sleep(1, "wait before verifying no packets sent")
        self.collector.assert_nothing_captured()

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")


@unittest.skipUnless(config.extended, "part of extended tests")
class ReenableIPFIX(MethodHolder):
    """Re-enable IPFIX"""

    @classmethod
    def setUpClass(cls):
        super(ReenableIPFIX, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(ReenableIPFIX, cls).tearDownClass()

    def test_0011(self):
        """disable IPFIX after first packets and re-enable after few packets"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder)

        self.create_stream(packets=5)
        self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        self.wait_for_cflow_packet(self.collector, templates[1])
        self.collector.get_capture(4)

        # disable IPFIX
        ipfix.disable_exporter()
        self.vapi.ipfix_flush()
        self.pg_enable_capture([self.collector])

        self.send_packets()

        # make sure no one packet arrived in active timer span
        self.vapi.ipfix_flush()
        self.sleep(1, "wait before verifying no packets sent")
        self.collector.assert_nothing_captured()
        self.pg2.get_capture(5)

        # enable IPFIX
        ipfix.enable_exporter()

        capture = self.collector.get_capture(4)
        nr_templates = 0
        nr_data = 0
        for p in capture:
            self.assertTrue(p.haslayer(IPFIX))
            if p.haslayer(Template):
                nr_templates += 1
        self.assertTrue(nr_templates, 3)
        for p in capture:
            self.assertTrue(p.haslayer(IPFIX))
            if p.haslayer(Data):
                nr_data += 1
        self.assertTrue(nr_templates, 1)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")


@unittest.skipUnless(config.extended, "part of extended tests")
class DisableFP(MethodHolder):
    """Disable Flowprobe feature"""

    @classmethod
    def setUpClass(cls):
        super(DisableFP, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(DisableFP, cls).tearDownClass()

    def test_0001(self):
        """disable flowprobe feature after first packets"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []
        ipfix = VppCFLOW(test=self)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        templates = ipfix.verify_templates(ipfix_decoder)

        self.create_stream()
        self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        self.wait_for_cflow_packet(self.collector, templates[1])
        self.collector.get_capture(4)

        # disable IPFIX
        ipfix.disable_flowprobe_feature()
        self.pg_enable_capture([self.collector])

        self.send_packets()

        # make sure no one packet arrived in active timer span
        self.vapi.ipfix_flush()
        self.sleep(1, "wait before verifying no packets sent")
        self.collector.assert_nothing_captured()

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")

    def test_no_leftover_flows_after_disabling(self):
        """disable flowprobe feature and expect no leftover flows"""
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        # enable ip4 datapath for an interface
        # set active and passive timers
        ipfix = VppCFLOW(
            test=self,
            active=3,
            passive=4,
            intf="pg3",
            layer="l3",
            datapath="ip4",
            direction="rx",
            mtu=100,
        )
        ipfix.add_vpp_config()

        # template packet should arrive immediately
        ipfix.verify_templates(count=1)

        # send some ip4 packets
        self.create_stream(src_if=self.pg3, dst_if=self.pg4, packets=5)
        self.send_packets(src_if=self.pg3, dst_if=self.pg4)

        # disable feature for the interface
        # currently stored ip4 flows should be removed
        ipfix.disable_flowprobe_feature()

        # no leftover ip4 flows are expected
        self.pg_enable_capture([self.collector])
        self.sleep(12, "wait for leftover ip4 flows during three passive intervals")
        self.collector.assert_nothing_captured()

        # cleanup
        ipfix.disable_exporter()


@unittest.skipUnless(config.extended, "part of extended tests")
class ReenableFP(MethodHolder):
    """Re-enable Flowprobe feature"""

    @classmethod
    def setUpClass(cls):
        super(ReenableFP, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(ReenableFP, cls).tearDownClass()

    def test_0001(self):
        """disable flowprobe feature after first packets and re-enable
        after few packets"""
        self.logger.info("FFP_TEST_START_0001")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self)
        ipfix.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        # template packet should arrive immediately
        self.vapi.ipfix_flush()
        templates = ipfix.verify_templates(ipfix_decoder, timeout=3)

        self.create_stream()
        self.send_packets()

        # make sure the one packet we expect actually showed up
        self.vapi.ipfix_flush()
        self.wait_for_cflow_packet(self.collector, templates[1], 5)
        self.collector.get_capture(4)

        # disable FPP feature
        ipfix.disable_flowprobe_feature()
        self.pg_enable_capture([self.collector])

        self.send_packets()

        # make sure no one packet arrived in active timer span
        self.vapi.ipfix_flush()
        self.sleep(5, "wait before verifying no packets sent")
        self.collector.assert_nothing_captured()

        # enable FPP feature
        ipfix.enable_flowprobe_feature()
        self.vapi.ipfix_flush()
        templates = ipfix.verify_templates(ipfix_decoder, timeout=3)

        self.send_packets()

        # make sure the next packets (templates and data) we expect actually
        # showed up
        self.vapi.ipfix_flush()
        self.wait_for_cflow_packet(self.collector, templates[1], 5)
        self.collector.get_capture(4)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0001")


if __name__ == "__main__":
    unittest.main(testRunner=VppTestRunner)
