#!/usr/bin/env python

from random import shuffle
import six
import unittest

from parameterized import parameterized
import scapy.compat
from scapy.packet import Raw
from scapy.layers.l2 import Ether, GRE
from scapy.layers.inet import IP, UDP, ICMP

from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment, ICMPv6ParamProblem,\
    ICMPv6TimeExceeded

from framework import VppTestCase, VppTestRunner
from util import ppp, fragment_rfc791, fragment_rfc8200
from vpp_gre_interface import VppGreInterface
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto

# 35 is enough to have >257 400-byte fragments
test_packet_count = 35

# <class 'scapy.layers.inet.IP'>
# <class 'scapy.layers.inet6.IPv6'>
_scapy_ip_family_types = (IP, IPv6)


def validate_scapy_ip_family(scapy_ip_family):

    if scapy_ip_family not in _scapy_ip_family_types:
        raise ValueError("'scapy_ip_family' must be of type: %s. Got %s" %
                         (_scapy_ip_family_types, scapy_ip_family))


class TestIPReassemblyMixin(object):

    def verify_capture(self, scapy_ip_family, capture,
                       dropped_packet_indexes=None):
        """Verify captured packet stream.

        :param list capture: Captured packet stream.
        """
        validate_scapy_ip_family(scapy_ip_family)

        if dropped_packet_indexes is None:
            dropped_packet_indexes = []
        info = None
        seen = set()
        for packet in capture:
            try:
                self.logger.debug(ppp("Got packet:", packet))
                ip = packet[scapy_ip_family]
                udp = packet[UDP]
                payload_info = self.payload_to_info(packet[Raw])
                packet_index = payload_info.index
                self.assertTrue(
                    packet_index not in dropped_packet_indexes,
                    ppp("Packet received, but should be dropped:", packet))
                if packet_index in seen:
                    raise Exception(ppp("Duplicate packet received", packet))
                seen.add(packet_index)
                self.assertEqual(payload_info.dst, self.src_if.sw_if_index)
                info = self._packet_infos[packet_index]
                self.assertTrue(info is not None)
                self.assertEqual(packet_index, info.index)
                saved_packet = info.data
                self.assertEqual(ip.src, saved_packet[scapy_ip_family].src)
                self.assertEqual(ip.dst, saved_packet[scapy_ip_family].dst)
                self.assertEqual(udp.payload, saved_packet[UDP].payload)
            except Exception:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        for index in self._packet_infos:
            self.assertTrue(index in seen or index in dropped_packet_indexes,
                            "Packet with packet_index %d not received" % index)

    def test_disabled(self, scapy_ip_family, stream,
                      dropped_packet_indexes):
        """ reassembly disabled """
        validate_scapy_ip_family(scapy_ip_family)
        is_ip6 = 1 if scapy_ip_family == IPv6 else 0

        self.vapi.ip_reassembly_set(timeout_ms=1000, max_reassemblies=0,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000,
                                    is_ip6=is_ip6)

        self.pg_enable_capture()
        self.src_if.add_stream(stream)
        self.pg_start()

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes))
        self.verify_capture(scapy_ip_family, packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    def test_duplicates(self, scapy_ip_family, stream):
        """ duplicate fragments """
        validate_scapy_ip_family(scapy_ip_family)

        self.pg_enable_capture()
        self.src_if.add_stream(stream)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

    def test_random(self, scapy_ip_family, stream):
        """ random order reassembly """
        validate_scapy_ip_family(scapy_ip_family)

        fragments = list(stream)
        shuffle(fragments)

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.packet_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

        # run it all again to verify correctness
        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.packet_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

    def test_reassembly(self, scapy_ip_family, stream):
        """ basic reassembly """
        validate_scapy_ip_family(scapy_ip_family)

        self.pg_enable_capture()
        self.src_if.add_stream(stream)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

        # run it all again to verify correctness
        self.pg_enable_capture()
        self.src_if.add_stream(stream)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

    def test_reversed(self, scapy_ip_family, stream):
        """ reverse order reassembly """
        validate_scapy_ip_family(scapy_ip_family)

        fragments = list(stream)
        fragments.reverse()

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.packet_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

        # run it all again to verify correctness
        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.packet_infos))
        self.verify_capture(scapy_ip_family, packets)
        self.src_if.assert_nothing_captured()

    def test_timeout_inline(self, scapy_ip_family, stream,
                            dropped_packet_indexes):
        """ timeout (inline) """
        validate_scapy_ip_family(scapy_ip_family)
        is_ip6 = 1 if scapy_ip_family == IPv6 else 0

        self.vapi.ip_reassembly_set(timeout_ms=0, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000,
                                    is_ip6=is_ip6)

        self.pg_enable_capture()
        self.src_if.add_stream(stream)
        self.pg_start()

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes))
        self.verify_capture(scapy_ip_family, packets,
                            dropped_packet_indexes)


class TestIPv4Reassembly(TestIPReassemblyMixin, VppTestCase):
    """ IPv4 Reassembly """

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

        cls.create_pg_interfaces([0, 1])
        cls.src_if = cls.pg0
        cls.dst_if = cls.pg1

        # setup all interfaces
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()

        # packet sizes
        cls.packet_sizes = [64, 512, 1518, 9018]
        cls.padding = " abcdefghijklmn"
        cls.create_stream(cls.packet_sizes)
        cls.create_fragments()

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

    def setUp(self):
        """ Test setup - force timeout on existing reassemblies """
        super(TestIPv4Reassembly, self).setUp()
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip4=True)
        self.vapi.ip_reassembly_set(timeout_ms=0, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10)
        self.sleep(.25)
        self.vapi.ip_reassembly_set(timeout_ms=1000000, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000)

    def tearDown(self):
        super(TestIPv4Reassembly, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))

    @classmethod
    def create_stream(cls, packet_sizes, packet_count=test_packet_count):
        """Create input packet stream

        :param list packet_sizes: Required packet sizes.
        """
        for i in range(0, packet_count):
            info = cls.create_packet_info(cls.src_if, cls.src_if)
            payload = cls.info_to_payload(info)
            p = (Ether(dst=cls.src_if.local_mac, src=cls.src_if.remote_mac) /
                 IP(id=info.index, src=cls.src_if.remote_ip4,
                    dst=cls.dst_if.remote_ip4) /
                 UDP(sport=1234, dport=5678) /
                 Raw(payload))
            size = packet_sizes[(i // 2) % len(packet_sizes)]
            cls.extend_packet(p, size, cls.padding)
            info.data = p

    @classmethod
    def create_fragments(cls):
        infos = cls._packet_infos
        cls.pkt_infos = []
        for index, info in six.iteritems(infos):
            p = info.data
            # cls.logger.debug(ppp("Packet:",
            #                      p.__class__(scapy.compat.raw(p))))
            fragments_400 = fragment_rfc791(p, 400)
            fragments_300 = fragment_rfc791(p, 300)
            fragments_200 = [
                x for f in fragments_400 for x in fragment_rfc791(f, 200)]
            cls.pkt_infos.append(
                (index, fragments_400, fragments_300, fragments_200))
        cls.fragments_400 = [
            x for (_, frags, _, _) in cls.pkt_infos for x in frags]
        cls.fragments_300 = [
            x for (_, _, frags, _) in cls.pkt_infos for x in frags]
        cls.fragments_200 = [
            x for (_, _, _, frags) in cls.pkt_infos for x in frags]
        cls.logger.debug("Fragmented %s packets into %s 400-byte fragments, "
                         "%s 300-byte fragments and %s 200-byte fragments" %
                         (len(infos), len(cls.fragments_400),
                             len(cls.fragments_300), len(cls.fragments_200)))

    @parameterized.expand([(IP, None)])
    def test_reassembly(self, family, stream):
        """ basic reassembly """
        stream = self.__class__.fragments_200
        super(TestIPv4Reassembly, self).test_reassembly(family, stream)

    @parameterized.expand([(IP, None)])
    def test_reversed(self, family, stream):
        """ reverse order reassembly """
        stream = self.__class__.fragments_200
        super(TestIPv4Reassembly, self).test_reversed(family, stream)

    @parameterized.expand([(IP, None)])
    def test_random(self, family, stream):
        stream = self.__class__.fragments_200
        super(TestIPv4Reassembly, self).test_random(family, stream)

    def test_long_fragment_chain(self):
        """ long fragment chain """

        error_cnt_str = \
            "/err/ip4-reassembly-feature/fragment chain too long (drop)"

        error_cnt = self.statistics.get_err_counter(error_cnt_str)

        self.vapi.ip_reassembly_set(timeout_ms=100, max_reassemblies=1000,
                                    max_reassembly_length=3,
                                    expire_walk_interval_ms=50)

        p1 = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
              IP(id=1000, src=self.src_if.remote_ip4,
                 dst=self.dst_if.remote_ip4) /
              UDP(sport=1234, dport=5678) /
              Raw("X" * 1000))
        p2 = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
              IP(id=1001, src=self.src_if.remote_ip4,
                 dst=self.dst_if.remote_ip4) /
              UDP(sport=1234, dport=5678) /
              Raw("X" * 1000))
        frags = fragment_rfc791(p1, 200) + fragment_rfc791(p2, 500)

        self.pg_enable_capture()
        self.src_if.add_stream(frags)
        self.pg_start()

        self.dst_if.get_capture(1)
        self.assert_error_counter_equal(error_cnt_str, error_cnt + 1)

    def test_5737(self):
        """ fragment length + ip header size > 65535 """
        self.vapi.cli("clear errors")
        raw = ('E\x00\x00\x88,\xf8\x1f\xfe@\x01\x98\x00\xc0\xa8\n-\xc0\xa8\n'
               '\x01\x08\x00\xf0J\xed\xcb\xf1\xf5Test-group: IPv4.IPv4.ipv4-'
               'message.Ethernet-Payload.IPv4-Packet.IPv4-Header.Fragment-Of'
               'fset; Test-case: 5737')

        malformed_packet = (Ether(dst=self.src_if.local_mac,
                                  src=self.src_if.remote_mac) /
                            IP(raw))
        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(id=1000, src=self.src_if.remote_ip4,
                dst=self.dst_if.remote_ip4) /
             UDP(sport=1234, dport=5678) /
             Raw("X" * 1000))
        valid_fragments = fragment_rfc791(p, 400)

        self.pg_enable_capture()
        self.src_if.add_stream([malformed_packet] + valid_fragments)
        self.pg_start()

        self.dst_if.get_capture(1)
        self.assert_packet_counter_equal("ip4-reassembly-feature", 1)
        # TODO remove above, uncomment below once clearing of counters
        # is supported
        # self.assert_packet_counter_equal(
        #     "/err/ip4-reassembly-feature/malformed packets", 1)

    def test_44924(self):
        """ compress tiny fragments """
        packets = [(Ether(dst=self.src_if.local_mac,
                          src=self.src_if.remote_mac) /
                    IP(id=24339, flags="MF", frag=0, ttl=64,
                       src=self.src_if.remote_ip4,
                       dst=self.dst_if.remote_ip4) /
                    ICMP(type="echo-request", code=0, id=0x1fe6, seq=0x2407) /
                    Raw(load='Test-group: IPv4')),
                   (Ether(dst=self.src_if.local_mac,
                          src=self.src_if.remote_mac) /
                    IP(id=24339, flags="MF", frag=3, ttl=64,
                       src=self.src_if.remote_ip4,
                       dst=self.dst_if.remote_ip4) /
                    ICMP(type="echo-request", code=0, id=0x1fe6, seq=0x2407) /
                    Raw(load='.IPv4.Fragmentation.vali')),
                   (Ether(dst=self.src_if.local_mac,
                          src=self.src_if.remote_mac) /
                    IP(id=24339, frag=6, ttl=64,
                       src=self.src_if.remote_ip4,
                       dst=self.dst_if.remote_ip4) /
                    ICMP(type="echo-request", code=0, id=0x1fe6, seq=0x2407) /
                    Raw(load='d; Test-case: 44924'))
                   ]

        self.pg_enable_capture()
        self.src_if.add_stream(packets)
        self.pg_start()

        self.dst_if.get_capture(1)

    def test_frag_1(self):
        """ fragment of size 1 """
        self.vapi.cli("clear errors")
        malformed_packets = [(Ether(dst=self.src_if.local_mac,
                                    src=self.src_if.remote_mac) /
                              IP(id=7, len=21, flags="MF", frag=0, ttl=64,
                                 src=self.src_if.remote_ip4,
                                 dst=self.dst_if.remote_ip4) /
                              ICMP(type="echo-request")),
                             (Ether(dst=self.src_if.local_mac,
                                    src=self.src_if.remote_mac) /
                              IP(id=7, len=21, frag=1, ttl=64,
                                 src=self.src_if.remote_ip4,
                                 dst=self.dst_if.remote_ip4) /
                              Raw(load='\x08')),
                             ]

        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(id=1000, src=self.src_if.remote_ip4,
                dst=self.dst_if.remote_ip4) /
             UDP(sport=1234, dport=5678) /
             Raw("X" * 1000))
        valid_fragments = fragment_rfc791(p, 400)

        self.pg_enable_capture()
        self.src_if.add_stream(malformed_packets + valid_fragments)
        self.pg_start()

        self.dst_if.get_capture(1)

        self.assert_packet_counter_equal("ip4-reassembly-feature", 1)
        # TODO remove above, uncomment below once clearing of counters
        # is supported
        # self.assert_packet_counter_equal(
        #     "/err/ip4-reassembly-feature/malformed packets", 1)

    @parameterized.expand([(IP, None)])
    def test_duplicates(self, family, stream):
        """ duplicate fragments """
        fragments = [
            # IPv4 uses 4 fields in pkt_infos, IPv6 uses 3.
            x for (_, frags, _, _) in self.pkt_infos
            for x in frags
            for _ in range(0, min(2, len(frags)))
        ]
        super(TestIPv4Reassembly, self).test_duplicates(family, fragments)

    def test_overlap1(self):
        """ overlapping fragments case #1 """

        fragments = []
        for _, _, frags_300, frags_200 in self.pkt_infos:
            if len(frags_300) == 1:
                fragments.extend(frags_300)
            else:
                for i, j in zip(frags_200, frags_300):
                    fragments.extend(i)
                    fragments.extend(j)

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(IP, packets)
        self.src_if.assert_nothing_captured()

        # run it all to verify correctness
        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(IP, packets)
        self.src_if.assert_nothing_captured()

    def test_overlap2(self):
        """ overlapping fragments case #2 """

        fragments = []
        for _, _, frags_300, frags_200 in self.pkt_infos:
            if len(frags_300) == 1:
                fragments.extend(frags_300)
            else:
                # care must be taken here so that there are no fragments
                # received by vpp after reassembly is finished, otherwise
                # new reassemblies will be started and packet generator will
                # freak out when it detects unfreed buffers
                zipped = zip(frags_300, frags_200)
                for i, j in zipped:
                    fragments.extend(i)
                    fragments.extend(j)
                fragments.pop()

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(IP, packets)
        self.src_if.assert_nothing_captured()

        # run it all to verify correctness
        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(IP, packets)
        self.src_if.assert_nothing_captured()

    @parameterized.expand([(IP, None, None)])
    def test_timeout_inline(self, family, stream, dropped_packet_indexes):
        """ timeout (inline) """
        stream = self.fragments_400

        dropped_packet_indexes = set(
            index for (index, frags, _, _) in self.pkt_infos if len(frags) > 1
        )
        super(TestIPv4Reassembly, self).test_timeout_inline(
            family, stream, dropped_packet_indexes)

        self.src_if.assert_nothing_captured()

    def test_timeout_cleanup(self):
        """ timeout (cleanup) """

        # whole packets + fragmented packets sans last fragment
        fragments = [
            x for (_, frags_400, _, _) in self.pkt_infos
            for x in frags_400[:-1 if len(frags_400) > 1 else None]
        ]

        # last fragments for fragmented packets
        fragments2 = [frags_400[-1]
                      for (_, frags_400, _, _) in self.pkt_infos
                      if len(frags_400) > 1]

        dropped_packet_indexes = set(
            index for (index, frags_400, _, _) in self.pkt_infos
            if len(frags_400) > 1)

        self.vapi.ip_reassembly_set(timeout_ms=100, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=50)

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        self.sleep(.25, "wait before sending rest of fragments")

        self.src_if.add_stream(fragments2)
        self.pg_start()

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes))
        self.verify_capture(IP, packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    @parameterized.expand([(IP, None, None)])
    def test_disabled(self, family, stream, dropped_packet_indexes):
        """ reassembly disabled """

        stream = self.__class__.fragments_400
        dropped_packet_indexes = set(
            index for (index, frags_400, _, _) in self.pkt_infos
            if len(frags_400) > 1)
        super(TestIPv4Reassembly, self).test_disabled(
            family, stream, dropped_packet_indexes)


class TestIPv6Reassembly(TestIPReassemblyMixin, VppTestCase):
    """ IPv6 Reassembly """

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

        cls.create_pg_interfaces([0, 1])
        cls.src_if = cls.pg0
        cls.dst_if = cls.pg1

        # setup all interfaces
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip6()
            i.resolve_ndp()

        # packet sizes
        cls.packet_sizes = [64, 512, 1518, 9018]
        cls.padding = " abcdefghijklmn"
        cls.create_stream(cls.packet_sizes)
        cls.create_fragments()

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

    def setUp(self):
        """ Test setup - force timeout on existing reassemblies """
        super(TestIPv6Reassembly, self).setUp()
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip6=True)
        self.vapi.ip_reassembly_set(timeout_ms=0, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10, is_ip6=1)
        self.sleep(.25)
        self.vapi.ip_reassembly_set(timeout_ms=1000000, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000, is_ip6=1)
        self.logger.debug(self.vapi.ppcli("show ip6-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))

    def tearDown(self):
        super(TestIPv6Reassembly, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip6-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))

    @classmethod
    def create_stream(cls, packet_sizes, packet_count=test_packet_count):
        """Create input packet stream for defined interface.

        :param list packet_sizes: Required packet sizes.
        """
        for i in range(0, packet_count):
            info = cls.create_packet_info(cls.src_if, cls.src_if)
            payload = cls.info_to_payload(info)
            p = (Ether(dst=cls.src_if.local_mac, src=cls.src_if.remote_mac) /
                 IPv6(src=cls.src_if.remote_ip6,
                      dst=cls.dst_if.remote_ip6) /
                 UDP(sport=1234, dport=5678) /
                 Raw(payload))
            size = packet_sizes[(i // 2) % len(packet_sizes)]
            cls.extend_packet(p, size, cls.padding)
            info.data = p

    @classmethod
    def create_fragments(cls):
        infos = cls._packet_infos
        cls.pkt_infos = []
        for index, info in six.iteritems(infos):
            p = info.data
            # cls.logger.debug(ppp("Packet:",
            #                      p.__class__(scapy.compat.raw(p))))
            fragments_400 = fragment_rfc8200(p, info.index, 400)
            fragments_300 = fragment_rfc8200(p, info.index, 300)
            cls.pkt_infos.append((index, fragments_400, fragments_300))
        cls.fragments_400 = [
            x for _, frags, _ in cls.pkt_infos for x in frags]
        cls.fragments_300 = [
            x for _, _, frags in cls.pkt_infos for x in frags]
        cls.logger.debug("Fragmented %s packets into %s 400-byte fragments, "
                         "and %s 300-byte fragments" %
                         (len(infos), len(cls.fragments_400),
                             len(cls.fragments_300)))

    @parameterized.expand([(IPv6, None)])
    def test_reassembly(self, family, stream):
        """ basic reassembly """
        stream = self.__class__.fragments_400
        super(TestIPv6Reassembly, self).test_reassembly(family, stream)

    @parameterized.expand([(IPv6, None)])
    def test_reversed(self, family, stream):
        """ reverse order reassembly """
        stream = self.__class__.fragments_400
        super(TestIPv6Reassembly, self).test_reversed(family, stream)

    @parameterized.expand([(IPv6, None)])
    def test_random(self, family, stream):
        """ random order reassembly """
        stream = self.__class__.fragments_400
        super(TestIPv6Reassembly, self).test_random(family, stream)

    @parameterized.expand([(IPv6, None)])
    def test_duplicates(self, family, stream):
        """ duplicate fragments """

        fragments = [
            # IPv4 uses 4 fields in pkt_infos, IPv6 uses 3.
            x for (_, frags, _) in self.pkt_infos
            for x in frags
            for _ in range(0, min(2, len(frags)))
        ]
        super(TestIPv6Reassembly, self).test_duplicates(family, fragments)

    def test_long_fragment_chain(self):
        """ long fragment chain """

        error_cnt_str = \
            "/err/ip6-reassembly-feature/fragment chain too long (drop)"

        error_cnt = self.statistics.get_err_counter(error_cnt_str)

        self.vapi.ip_reassembly_set(timeout_ms=100, max_reassemblies=1000,
                                    max_reassembly_length=3,
                                    expire_walk_interval_ms=50, is_ip6=1)

        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.src_if.remote_ip6,
                  dst=self.dst_if.remote_ip6) /
             UDP(sport=1234, dport=5678) /
             Raw("X" * 1000))
        frags = fragment_rfc8200(p, 1, 300) + fragment_rfc8200(p, 2, 500)

        self.pg_enable_capture()
        self.src_if.add_stream(frags)
        self.pg_start()

        self.dst_if.get_capture(1)
        self.assert_error_counter_equal(error_cnt_str, error_cnt + 1)

    def test_overlap1(self):
        """ overlapping fragments case #1 (differs from IP test case)"""

        fragments = []
        for _, frags_400, frags_300 in self.pkt_infos:
            if len(frags_300) == 1:
                fragments.extend(frags_400)
            else:
                for i, j in zip(frags_300, frags_400):
                    fragments.extend(i)
                    fragments.extend(j)

        dropped_packet_indexes = set(
            index for (index, _, frags) in self.pkt_infos if len(frags) > 1
        )

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes))
        self.verify_capture(IPv6, packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    def test_overlap2(self):
        """ overlapping fragments case #2 (differs from IP test case)"""

        fragments = []
        for _, frags_400, frags_300 in self.pkt_infos:
            if len(frags_400) == 1:
                fragments.extend(frags_400)
            else:
                # care must be taken here so that there are no fragments
                # received by vpp after reassembly is finished, otherwise
                # new reassemblies will be started and packet generator will
                # freak out when it detects unfreed buffers
                zipped = zip(frags_400, frags_300)
                for i, j in zipped:
                    fragments.extend(i)
                    fragments.extend(j)
                fragments.pop()

        dropped_packet_indexes = set(
            index for (index, _, frags) in self.pkt_infos if len(frags) > 1
        )

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes))
        self.verify_capture(IPv6, packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    @parameterized.expand([(IPv6, None, None)])
    def test_timeout_inline(self, family, stream, dropped_packets_index):
        """ timeout (inline) """
        stream = self.__class__.fragments_400

        dropped_packet_indexes = set(
            index for (index, frags, _) in self.pkt_infos if len(frags) > 1
        )
        super(TestIPv6Reassembly, self).test_timeout_inline(
            family, stream, dropped_packet_indexes)

        pkts = self.src_if.get_capture(
            expected_count=len(dropped_packet_indexes))
        for icmp in pkts:
            self.assertIn(ICMPv6TimeExceeded, icmp)
            self.assertIn(IPv6ExtHdrFragment, icmp)
            self.assertIn(icmp[IPv6ExtHdrFragment].id, dropped_packet_indexes)
            dropped_packet_indexes.remove(icmp[IPv6ExtHdrFragment].id)

    def test_timeout_cleanup(self):
        """ timeout (cleanup) """

        # whole packets + fragmented packets sans last fragment
        fragments = [
            x for (_, frags_400, _) in self.pkt_infos
            for x in frags_400[:-1 if len(frags_400) > 1 else None]
        ]

        # last fragments for fragmented packets
        fragments2 = [frags_400[-1]
                      for (_, frags_400, _) in self.pkt_infos
                      if len(frags_400) > 1]

        dropped_packet_indexes = set(
            index for (index, frags_400, _) in self.pkt_infos
            if len(frags_400) > 1)

        self.vapi.ip_reassembly_set(timeout_ms=100, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=50)

        self.vapi.ip_reassembly_set(timeout_ms=100, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=50, is_ip6=1)

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()

        self.sleep(.25, "wait before sending rest of fragments")

        self.src_if.add_stream(fragments2)
        self.pg_start()

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes))
        self.verify_capture(IPv6, packets, dropped_packet_indexes)
        pkts = self.src_if.get_capture(
            expected_count=len(dropped_packet_indexes))
        for icmp in pkts:
            self.assertIn(ICMPv6TimeExceeded, icmp)
            self.assertIn(IPv6ExtHdrFragment, icmp)
            self.assertIn(icmp[IPv6ExtHdrFragment].id, dropped_packet_indexes)
            dropped_packet_indexes.remove(icmp[IPv6ExtHdrFragment].id)

    @parameterized.expand([(IPv6, None, None)])
    def test_disabled(self, family, stream, dropped_packet_indexes):
        """ reassembly disabled """

        stream = self.__class__.fragments_400
        dropped_packet_indexes = set(
            index for (index, frags_400, _) in self.pkt_infos
            if len(frags_400) > 1)
        super(TestIPv6Reassembly, self).test_disabled(
            family, stream, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    def test_missing_upper(self):
        """ missing upper layer """
        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.src_if.remote_ip6,
                  dst=self.src_if.local_ip6) /
             UDP(sport=1234, dport=5678) /
             Raw())
        self.extend_packet(p, 1000, self.padding)
        fragments = fragment_rfc8200(p, 1, 500)
        bad_fragment = p.__class__(scapy.compat.raw(fragments[1]))
        bad_fragment[IPv6ExtHdrFragment].nh = 59
        bad_fragment[IPv6ExtHdrFragment].offset = 0
        self.pg_enable_capture()
        self.src_if.add_stream([bad_fragment])
        self.pg_start()
        pkts = self.src_if.get_capture(expected_count=1)
        icmp = pkts[0]
        self.assertIn(ICMPv6ParamProblem, icmp)
        self.assert_equal(icmp[ICMPv6ParamProblem].code, 3, "ICMP code")

    def test_invalid_frag_size(self):
        """ fragment size not a multiple of 8 """
        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.src_if.remote_ip6,
                  dst=self.src_if.local_ip6) /
             UDP(sport=1234, dport=5678) /
             Raw())
        self.extend_packet(p, 1000, self.padding)
        fragments = fragment_rfc8200(p, 1, 500)
        bad_fragment = fragments[0]
        self.extend_packet(bad_fragment, len(bad_fragment) + 5)
        self.pg_enable_capture()
        self.src_if.add_stream([bad_fragment])
        self.pg_start()
        pkts = self.src_if.get_capture(expected_count=1)
        icmp = pkts[0]
        self.assertIn(ICMPv6ParamProblem, icmp)
        self.assert_equal(icmp[ICMPv6ParamProblem].code, 0, "ICMP code")

    def test_invalid_packet_size(self):
        """ total packet size > 65535 """
        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.src_if.remote_ip6,
                  dst=self.src_if.local_ip6) /
             UDP(sport=1234, dport=5678) /
             Raw())
        self.extend_packet(p, 1000, self.padding)
        fragments = fragment_rfc8200(p, 1, 500)
        bad_fragment = fragments[1]
        bad_fragment[IPv6ExtHdrFragment].offset = 65500
        self.pg_enable_capture()
        self.src_if.add_stream([bad_fragment])
        self.pg_start()
        pkts = self.src_if.get_capture(expected_count=1)
        icmp = pkts[0]
        self.assertIn(ICMPv6ParamProblem, icmp)
        self.assert_equal(icmp[ICMPv6ParamProblem].code, 0, "ICMP code")


class TestIPv4ReassemblyLocalNode(VppTestCase):
    """ IPv4 Reassembly for packets coming to ip4-local node """

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

        cls.create_pg_interfaces([0])
        cls.src_dst_if = cls.pg0

        # setup all interfaces
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()

        cls.padding = " abcdefghijklmn"
        cls.create_stream()
        cls.create_fragments()

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

    def setUp(self):
        """ Test setup - force timeout on existing reassemblies """
        super(TestIPv4ReassemblyLocalNode, self).setUp()
        self.vapi.ip_reassembly_set(timeout_ms=0, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10)
        self.sleep(.25)
        self.vapi.ip_reassembly_set(timeout_ms=1000000, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000)

    def tearDown(self):
        super(TestIPv4ReassemblyLocalNode, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))

    @classmethod
    def create_stream(cls, packet_count=test_packet_count):
        """Create input packet stream for defined interface.

        :param list packet_sizes: Required packet sizes.
        """
        for i in range(0, packet_count):
            info = cls.create_packet_info(cls.src_dst_if, cls.src_dst_if)
            payload = cls.info_to_payload(info)
            p = (Ether(dst=cls.src_dst_if.local_mac,
                       src=cls.src_dst_if.remote_mac) /
                 IP(id=info.index, src=cls.src_dst_if.remote_ip4,
                    dst=cls.src_dst_if.local_ip4) /
                 ICMP(type='echo-request', id=1234) /
                 Raw(payload))
            cls.extend_packet(p, 1518, cls.padding)
            info.data = p

    @classmethod
    def create_fragments(cls):
        infos = cls._packet_infos
        cls.pkt_infos = []
        for index, info in six.iteritems(infos):
            p = info.data
            # cls.logger.debug(ppp("Packet:",
            #                      p.__class__(scapy.compat.raw(p))))
            fragments_300 = fragment_rfc791(p, 300)
            cls.pkt_infos.append((index, fragments_300))
        cls.fragments_300 = [x for (_, frags) in cls.pkt_infos for x in frags]
        cls.logger.debug("Fragmented %s packets into %s 300-byte fragments" %
                         (len(infos), len(cls.fragments_300)))

    def verify_capture(self, capture):
        """Verify captured packet stream.

        :param list capture: Captured packet stream.
        """
        info = None
        seen = set()
        for packet in capture:
            try:
                self.logger.debug(ppp("Got packet:", packet))
                ip = packet[IP]
                icmp = packet[ICMP]
                payload_info = self.payload_to_info(packet[Raw])
                packet_index = payload_info.index
                if packet_index in seen:
                    raise Exception(ppp("Duplicate packet received", packet))
                seen.add(packet_index)
                self.assertEqual(payload_info.dst, self.src_dst_if.sw_if_index)
                info = self._packet_infos[packet_index]
                self.assertIsNotNone(info)
                self.assertEqual(packet_index, info.index)
                saved_packet = info.data
                self.assertEqual(ip.src, saved_packet[IP].dst)
                self.assertEqual(ip.dst, saved_packet[IP].src)
                self.assertEqual(icmp.type, 0)  # echo reply
                self.assertEqual(icmp.id, saved_packet[ICMP].id)
                self.assertEqual(icmp.payload, saved_packet[ICMP].payload)
            except Exception:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        for index in self._packet_infos:
            self.assertIn(index, seen,
                          "Packet with packet_index %d not received" % index)

    def test_reassembly(self):
        """ basic reassembly """

        self.pg_enable_capture()
        self.src_dst_if.add_stream(self.fragments_300)
        self.pg_start()

        packets = self.src_dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)

        # run it all again to verify correctness
        self.pg_enable_capture()
        self.src_dst_if.add_stream(self.fragments_300)
        self.pg_start()

        packets = self.src_dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)


class TestFIFReassembly(VppTestCase):
    """ Fragments in fragments reassembly """

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

        cls.create_pg_interfaces([0, 1])
        cls.src_if = cls.pg0
        cls.dst_if = cls.pg1
        for i in cls.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()
            i.config_ip6()
            i.resolve_ndp()

        cls.packet_sizes = [64, 512, 1518, 9018]
        cls.padding = " abcdefghijklmn"

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

    def setUp(self):
        """ Test setup - force timeout on existing reassemblies """
        super(TestFIFReassembly, self).setUp()
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip4=True,
            enable_ip6=True)
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.dst_if.sw_if_index, enable_ip4=True,
            enable_ip6=True)
        self.vapi.ip_reassembly_set(timeout_ms=0, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10)
        self.vapi.ip_reassembly_set(timeout_ms=0, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10, is_ip6=1)
        self.sleep(.25)
        self.vapi.ip_reassembly_set(timeout_ms=1000000, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000)
        self.vapi.ip_reassembly_set(timeout_ms=1000000, max_reassemblies=1000,
                                    max_reassembly_length=1000,
                                    expire_walk_interval_ms=10000, is_ip6=1)

    def tearDown(self):
        super(TestFIFReassembly, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show ip6-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))

    def verify_capture(self, capture, ip_class, dropped_packet_indexes=[]):
        """Verify captured packet stream.

        :param list capture: Captured packet stream.
        """
        info = None
        seen = set()
        for packet in capture:
            try:
                self.logger.debug(ppp("Got packet:", packet))
                ip = packet[ip_class]
                udp = packet[UDP]
                payload_info = self.payload_to_info(packet[Raw])
                packet_index = payload_info.index
                self.assertTrue(
                    packet_index not in dropped_packet_indexes,
                    ppp("Packet received, but should be dropped:", packet))
                if packet_index in seen:
                    raise Exception(ppp("Duplicate packet received", packet))
                seen.add(packet_index)
                self.assertEqual(payload_info.dst, self.dst_if.sw_if_index)
                info = self._packet_infos[packet_index]
                self.assertTrue(info is not None)
                self.assertEqual(packet_index, info.index)
                saved_packet = info.data
                self.assertEqual(ip.src, saved_packet[ip_class].src)
                self.assertEqual(ip.dst, saved_packet[ip_class].dst)
                self.assertEqual(udp.payload, saved_packet[UDP].payload)
            except Exception:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        for index in self._packet_infos:
            self.assertTrue(index in seen or index in dropped_packet_indexes,
                            "Packet with packet_index %d not received" % index)

    def test_fif4(self):
        """ Fragments in fragments (4o4) """

        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip4 = "1.1.1.2"

        self.gre4 = VppGreInterface(self, self.src_if.local_ip4, self.tun_ip4)
        self.gre4.add_vpp_config()
        self.gre4.admin_up()
        self.gre4.config_ip4()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre4.sw_if_index, enable_ip4=True)

        self.route4 = VppIpRoute(self, self.tun_ip4, 32,
                                 [VppRoutePath(self.src_if.remote_ip4,
                                               self.src_if.sw_if_index)])
        self.route4.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() /
                 IP(id=i, src=self.src_if.remote_ip4,
                    dst=self.dst_if.remote_ip4) /
                 UDP(sport=1234, dport=5678) /
                 Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IP]  # use only IP part, without ethernet header

        fragments = [x for _, p in six.iteritems(self._packet_infos)
                     for x in fragment_rfc791(p.data, 400)]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(src=self.tun_ip4, dst=self.src_if.local_ip4) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments
             for x in fragment_rfc791(p, 200)]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IP)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre4.remove_vpp_config()
        self.logger.debug(self.vapi.ppcli("show interface"))

    def test_fif6(self):
        """ Fragments in fragments (6o6) """
        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip6 = "1002::1"

        self.gre6 = VppGreInterface(self, self.src_if.local_ip6, self.tun_ip6)
        self.gre6.add_vpp_config()
        self.gre6.admin_up()
        self.gre6.config_ip6()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre6.sw_if_index, enable_ip6=True)

        self.route6 = VppIpRoute(self, self.tun_ip6, 128,
                                 [VppRoutePath(
                                     self.src_if.remote_ip6,
                                     self.src_if.sw_if_index)])
        self.route6.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() /
                 IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6) /
                 UDP(sport=1234, dport=5678) /
                 Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IPv6]  # use only IPv6 part, without ethernet header

        fragments = [x for _, i in six.iteritems(self._packet_infos)
                     for x in fragment_rfc8200(
                         i.data, i.index, 400)]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.tun_ip6, dst=self.src_if.local_ip6) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments for x in (
                fragment_rfc8200(
                    p,
                    2 * len(self._packet_infos) + p[IPv6ExtHdrFragment].id,
                    200)
                if IPv6ExtHdrFragment in p else [p]
            )
            ]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IPv6)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre6.remove_vpp_config()


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