#!/usr/bin/env python3

import unittest
from random import shuffle, randrange

from framework import VppTestCase
from asfframework import VppTestRunner

from scapy.packet import Raw
from scapy.layers.l2 import Ether, GRE
from scapy.layers.inet import IP, UDP, ICMP, icmptypes
from scapy.layers.inet6 import (
    HBHOptUnknown,
    ICMPv6ParamProblem,
    ICMPv6TimeExceeded,
    IPv6,
    IPv6ExtHdrFragment,
    IPv6ExtHdrHopByHop,
    IPv6ExtHdrDestOpt,
    PadN,
    ICMPv6EchoRequest,
    ICMPv6EchoReply,
)
from util import ppp, fragment_rfc791, fragment_rfc8200
from vpp_gre_interface import VppGreInterface
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_papi import VppEnum

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


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

    @classmethod
    def setUpClass(cls):
        super().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().tearDownClass()

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().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.virtual_sleep(0.25)
        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            expire_walk_interval_ms=10000,
        )

    def tearDown(self):
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip4=False
        )
        super().tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-full-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 infos.items():
            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),
            )
        )

    def verify_capture(self, capture, 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]
                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[IP].src)
                self.assertEqual(ip.dst, saved_packet[IP].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_reassembly(self):
        """basic reassembly"""

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

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

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

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

    def test_verify_clear_trace_mid_reassembly(self):
        """verify clear trace works mid-reassembly"""

        self.pg_enable_capture()
        self.src_if.add_stream(self.fragments_200[0:-1])
        self.pg_start()

        self.logger.debug(self.vapi.cli("show trace"))
        self.vapi.cli("clear trace")

        self.src_if.add_stream(self.fragments_200[-1])
        self.pg_start()
        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)

    def test_reversed(self):
        """reverse order reassembly"""

        fragments = list(self.fragments_200)
        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(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(packets)
        self.src_if.assert_nothing_captured()

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

        error_cnt_str = "/err/ip4-full-reassembly-feature/reass_fragment_chain_too_long"

        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(b"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(b"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 = b"""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-Offset; 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(b"X" * 1000)
        )
        valid_fragments = fragment_rfc791(p, 400)

        counter = "/err/ip4-full-reassembly-feature/reass_malformed_packet"
        error_counter = self.statistics.get_err_counter(counter)
        self.pg_enable_capture()
        self.src_if.add_stream([malformed_packet] + valid_fragments)
        self.pg_start()

        self.dst_if.get_capture(1)
        self.logger.debug(self.vapi.ppcli("show error"))
        self.assertEqual(self.statistics.get_err_counter(counter), error_counter + 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=b"\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(b"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-full-reassembly-feature", 1)
        # TODO remove above, uncomment below once clearing of counters
        # is supported
        # self.assert_packet_counter_equal(
        #     "/err/ip4-full-reassembly-feature/reass_malformed_packet", 1)

    def test_random(self):
        """random order reassembly"""

        fragments = list(self.fragments_200)
        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(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(packets)
        self.src_if.assert_nothing_captured()

    def test_duplicates(self):
        """duplicate fragments"""

        fragments = [
            x
            for (_, frags, _, _) in self.pkt_infos
            for x in frags
            for _ in range(0, min(2, len(frags)))
        ]

        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(packets)
        self.src_if.assert_nothing_captured()

    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(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(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(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(packets)
        self.src_if.assert_nothing_captured()

    def test_timeout_inline(self):
        """timeout (inline)"""

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

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

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

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes)
        )
        self.verify_capture(packets, 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.virtual_sleep(0.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(packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    def test_disabled(self):
        """reassembly disabled"""

        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=1000,
            max_reassemblies=0,
            max_reassembly_length=3,
            expire_walk_interval_ms=10000,
        )

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

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

    def test_local_enable_disable(self):
        """local reassembly enabled/disable"""
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip4=False
        )
        self.vapi.ip_local_reass_enable_disable(enable_ip4=True)
        p = (
            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
            / IP(src=self.src_if.remote_ip4, dst=self.src_if.local_ip4)
            / ICMP(id=1234, type="echo-request")
            / Raw("x" * 1000)
        )
        frags = fragment_rfc791(p, 400)
        r = self.send_and_expect(self.src_if, frags, self.src_if, n_rx=1)[0]
        self.assertEqual(1234, r[ICMP].id)
        self.assertEqual(icmptypes[r[ICMP].type], "echo-reply")
        self.vapi.ip_local_reass_enable_disable()

        self.send_and_assert_no_replies(self.src_if, frags)
        self.vapi.ip_local_reass_enable_disable(enable_ip4=True)


class TestIPv4SVReassembly(VppTestCase):
    """IPv4 Shallow Virtual Reassembly"""

    @classmethod
    def setUpClass(cls):
        super().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()

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().setUp()
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index,
            enable_ip4=True,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
        )
        self.vapi.ip_reassembly_set(
            timeout_ms=0,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
            expire_walk_interval_ms=10,
        )
        self.virtual_sleep(0.25)
        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
            expire_walk_interval_ms=10000,
        )

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

    def test_basic(self):
        """basic reassembly"""
        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 1

        p = (
            Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac)
            / IP(id=1, src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4)
            / UDP(sport=1234, dport=5678)
            / Raw(payload)
        )
        fragments = fragment_rfc791(p, payload_len / 4)

        # send fragment #2 - should be cached inside reassembly
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[1])
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip4-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        self.dst_if.assert_nothing_captured()

        # send fragment #1 - reassembly is finished now and both fragments
        # forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[0])
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip4-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        c = self.dst_if.get_capture(2)
        for sent, recvd in zip([fragments[1], fragments[0]], c):
            self.assertEqual(sent[IP].src, recvd[IP].src)
            self.assertEqual(sent[IP].dst, recvd[IP].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

        # send rest of fragments - should be immediately forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[2:])
        self.pg_start()
        c = self.dst_if.get_capture(len(fragments[2:]))
        for sent, recvd in zip(fragments[2:], c):
            self.assertEqual(sent[IP].src, recvd[IP].src)
            self.assertEqual(sent[IP].dst, recvd[IP].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

    def test_verify_clear_trace_mid_reassembly(self):
        """verify clear trace works mid-reassembly"""
        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 1

        p = (
            Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac)
            / IP(id=1, src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4)
            / UDP(sport=1234, dport=5678)
            / Raw(payload)
        )
        fragments = fragment_rfc791(p, payload_len / 4)

        self.pg_enable_capture()
        self.src_if.add_stream(fragments[1])
        self.pg_start()

        self.logger.debug(self.vapi.cli("show trace"))
        self.vapi.cli("clear trace")

        self.pg_enable_capture()
        self.src_if.add_stream(fragments[0])
        self.pg_start()
        self.dst_if.get_capture(2)

        self.logger.debug(self.vapi.cli("show trace"))
        self.vapi.cli("clear trace")

        self.pg_enable_capture()
        self.src_if.add_stream(fragments[2:])
        self.pg_start()
        self.dst_if.get_capture(len(fragments[2:]))

    def test_timeout(self):
        """reassembly timeout"""
        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 1

        p = (
            Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac)
            / IP(id=1, src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4)
            / UDP(sport=1234, dport=5678)
            / Raw(payload)
        )
        fragments = fragment_rfc791(p, payload_len / 4)

        self.vapi.ip_reassembly_set(
            timeout_ms=100,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            expire_walk_interval_ms=50,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
        )

        # send fragments #2 and #1 - should be forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[0:2])
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip4-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        c = self.dst_if.get_capture(2)
        for sent, recvd in zip([fragments[1], fragments[0]], c):
            self.assertEqual(sent[IP].src, recvd[IP].src)
            self.assertEqual(sent[IP].dst, recvd[IP].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

        # wait for cleanup
        self.virtual_sleep(0.25, "wait before sending rest of fragments")

        # send rest of fragments - shouldn't be forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[2:])
        self.pg_start()
        self.dst_if.assert_nothing_captured()

    def test_lru(self):
        """reassembly reuses LRU element"""

        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1,
            max_reassembly_length=1000,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
            expire_walk_interval_ms=10000,
        )

        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 1

        packet_count = 10

        fragments = [
            f
            for i in range(packet_count)
            for p in (
                Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac)
                / IP(id=i, src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4)
                / UDP(sport=1234, dport=5678)
                / Raw(payload)
            )
            for f in fragment_rfc791(p, payload_len / 4)
        ]

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()
        c = self.dst_if.get_capture(len(fragments))
        for sent, recvd in zip(fragments, c):
            self.assertEqual(sent[IP].src, recvd[IP].src)
            self.assertEqual(sent[IP].dst, recvd[IP].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

    def send_mixed_and_verify_capture(self, traffic):
        stream = []
        for t in traffic:
            for c in range(t["count"]):
                stream.append(
                    (
                        Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac)
                        / IP(
                            id=self.counter,
                            flags=t["flags"],
                            src=self.src_if.remote_ip4,
                            dst=self.dst_if.remote_ip4,
                        )
                        / UDP(sport=1234, dport=5678)
                        / Raw("abcdef")
                    )
                )
                self.counter = self.counter + 1

        self.pg_enable_capture()
        self.src_if.add_stream(stream)
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip4-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        self.dst_if.get_capture(len(stream))

    def test_mixed(self):
        """mixed traffic correctly passes through SVR"""
        self.counter = 1

        self.send_mixed_and_verify_capture([{"count": 1, "flags": ""}])
        self.send_mixed_and_verify_capture([{"count": 2, "flags": ""}])
        self.send_mixed_and_verify_capture([{"count": 3, "flags": ""}])
        self.send_mixed_and_verify_capture([{"count": 8, "flags": ""}])
        self.send_mixed_and_verify_capture([{"count": 257, "flags": ""}])

        self.send_mixed_and_verify_capture([{"count": 1, "flags": "MF"}])
        self.send_mixed_and_verify_capture([{"count": 2, "flags": "MF"}])
        self.send_mixed_and_verify_capture([{"count": 3, "flags": "MF"}])
        self.send_mixed_and_verify_capture([{"count": 8, "flags": "MF"}])
        self.send_mixed_and_verify_capture([{"count": 257, "flags": "MF"}])

        self.send_mixed_and_verify_capture(
            [{"count": 1, "flags": ""}, {"count": 1, "flags": "MF"}]
        )
        self.send_mixed_and_verify_capture(
            [{"count": 2, "flags": ""}, {"count": 2, "flags": "MF"}]
        )
        self.send_mixed_and_verify_capture(
            [{"count": 3, "flags": ""}, {"count": 3, "flags": "MF"}]
        )
        self.send_mixed_and_verify_capture(
            [{"count": 8, "flags": ""}, {"count": 8, "flags": "MF"}]
        )
        self.send_mixed_and_verify_capture(
            [{"count": 129, "flags": ""}, {"count": 129, "flags": "MF"}]
        )

        self.send_mixed_and_verify_capture(
            [
                {"count": 1, "flags": ""},
                {"count": 1, "flags": "MF"},
                {"count": 1, "flags": ""},
                {"count": 1, "flags": "MF"},
            ]
        )
        self.send_mixed_and_verify_capture(
            [
                {"count": 2, "flags": ""},
                {"count": 2, "flags": "MF"},
                {"count": 2, "flags": ""},
                {"count": 2, "flags": "MF"},
            ]
        )
        self.send_mixed_and_verify_capture(
            [
                {"count": 3, "flags": ""},
                {"count": 3, "flags": "MF"},
                {"count": 3, "flags": ""},
                {"count": 3, "flags": "MF"},
            ]
        )
        self.send_mixed_and_verify_capture(
            [
                {"count": 8, "flags": ""},
                {"count": 8, "flags": "MF"},
                {"count": 8, "flags": ""},
                {"count": 8, "flags": "MF"},
            ]
        )
        self.send_mixed_and_verify_capture(
            [
                {"count": 65, "flags": ""},
                {"count": 65, "flags": "MF"},
                {"count": 65, "flags": ""},
                {"count": 65, "flags": "MF"},
            ]
        )


class TestIPv4MWReassembly(VppTestCase):
    """IPv4 Reassembly (multiple workers)"""

    vpp_worker_count = 3

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

        cls.create_pg_interfaces(range(cls.vpp_worker_count + 1))
        cls.src_if = cls.pg0
        cls.send_ifs = cls.pg_interfaces[:-1]
        cls.dst_if = cls.pg_interfaces[-1]

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

        # packets sizes reduced here because we are generating packets without
        # Ethernet headers, which are added later (diff fragments go via
        # different interfaces)
        cls.packet_sizes = [
            64 - len(Ether()),
            512 - len(Ether()),
            1518 - len(Ether()),
            9018 - len(Ether()),
        ]
        cls.padding = " abcdefghijklmn"
        cls.create_stream(cls.packet_sizes)
        cls.create_fragments()

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

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().setUp()
        for intf in self.send_ifs:
            self.vapi.ip_reassembly_enable_disable(
                sw_if_index=intf.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.virtual_sleep(0.25)
        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            expire_walk_interval_ms=10000,
        )

    def tearDown(self):
        for intf in self.send_ifs:
            self.vapi.ip_reassembly_enable_disable(
                sw_if_index=intf.sw_if_index, enable_ip4=False
            )
        super().tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-full-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 = (
                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 infos.items():
            p = info.data
            # cls.logger.debug(ppp("Packet:",
            #                      p.__class__(scapy.compat.raw(p))))
            fragments_400 = fragment_rfc791(p, 400)
            cls.pkt_infos.append((index, fragments_400))
        cls.fragments_400 = [x for (_, frags) in cls.pkt_infos for x in frags]
        cls.logger.debug(
            "Fragmented %s packets into %s 400-byte fragments, "
            % (len(infos), len(cls.fragments_400))
        )

    def verify_capture(self, capture, 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]
                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[IP].src)
                self.assertEqual(ip.dst, saved_packet[IP].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 send_packets(self, packets):
        for counter in range(self.vpp_worker_count):
            if 0 == len(packets[counter]):
                continue
            send_if = self.send_ifs[counter]
            send_if.add_stream(
                (
                    Ether(dst=send_if.local_mac, src=send_if.remote_mac) / x
                    for x in packets[counter]
                ),
                worker=counter,
            )
        self.pg_start()

    def test_worker_conflict(self):
        """1st and FO=0 fragments on different workers"""

        # in first wave we send fragments which don't start at offset 0
        # then we send fragments with offset 0 on a different thread
        # then the rest of packets on a random thread
        first_packets = [[] for n in range(self.vpp_worker_count)]
        second_packets = [[] for n in range(self.vpp_worker_count)]
        rest_of_packets = [[] for n in range(self.vpp_worker_count)]
        for _, p in self.pkt_infos:
            wi = randrange(self.vpp_worker_count)
            second_packets[wi].append(p[0])
            if len(p) <= 1:
                continue
            wi2 = wi
            while wi2 == wi:
                wi2 = randrange(self.vpp_worker_count)
            first_packets[wi2].append(p[1])
            wi3 = randrange(self.vpp_worker_count)
            rest_of_packets[wi3].extend(p[2:])

        self.pg_enable_capture()
        self.send_packets(first_packets)
        self.send_packets(second_packets)
        self.send_packets(rest_of_packets)

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)
        for send_if in self.send_ifs:
            send_if.assert_nothing_captured()

        self.logger.debug(self.vapi.ppcli("show trace"))
        self.logger.debug(self.vapi.ppcli("show ip4-full-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.vapi.cli("clear trace")

        self.pg_enable_capture()
        self.send_packets(first_packets)
        self.send_packets(second_packets)
        self.send_packets(rest_of_packets)

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)
        for send_if in self.send_ifs:
            send_if.assert_nothing_captured()


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

    @classmethod
    def setUpClass(cls):
        super().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().tearDownClass()

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().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.virtual_sleep(0.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-full-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))

    def tearDown(self):
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip6=False
        )
        super().tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip6-full-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 infos.items():
            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))
        )

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

        :param list capture: Captured packet stream.
        """
        info = None
        seen = set()
        for packet in capture:
            try:
                self.logger.debug(ppp("Got packet:", packet))
                ip = packet[IPv6]
                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[IPv6].src)
                self.assertEqual(ip.dst, saved_packet[IPv6].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_reassembly(self):
        """basic reassembly"""

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

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

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

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

    def test_buffer_boundary(self):
        """fragment header crossing buffer boundary"""

        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)
            / IPv6ExtHdrHopByHop(options=[HBHOptUnknown(otype=0xFF, optlen=0)] * 1000)
            / IPv6ExtHdrFragment(m=1)
            / UDP(sport=1234, dport=5678)
            / Raw()
        )
        self.pg_enable_capture()
        self.src_if.add_stream([p])
        self.pg_start()
        self.src_if.assert_nothing_captured()
        self.dst_if.assert_nothing_captured()

    def test_verify_clear_trace_mid_reassembly(self):
        """verify clear trace works mid-reassembly"""

        self.pg_enable_capture()
        self.src_if.add_stream(self.fragments_400[0:-1])
        self.pg_start()

        self.logger.debug(self.vapi.cli("show trace"))
        self.vapi.cli("clear trace")

        self.src_if.add_stream(self.fragments_400[-1])
        self.pg_start()
        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)

    def test_reversed(self):
        """reverse order reassembly"""

        fragments = list(self.fragments_400)
        fragments.reverse()

        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(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.pkt_infos))
        self.verify_capture(packets)
        self.src_if.assert_nothing_captured()

    def test_random(self):
        """random order reassembly"""

        fragments = list(self.fragments_400)
        shuffle(fragments)

        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(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.pkt_infos))
        self.verify_capture(packets)
        self.src_if.assert_nothing_captured()

    def test_duplicates(self):
        """duplicate fragments"""

        fragments = [
            x
            for (_, frags, _) in self.pkt_infos
            for x in frags
            for _ in range(0, min(2, len(frags)))
        ]

        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(packets)
        self.src_if.assert_nothing_captured()

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

        error_cnt_str = "/err/ip6-full-reassembly-feature/reass_fragment_chain_too_long"

        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(b"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"""

        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(packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

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

        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(packets, dropped_packet_indexes)
        self.src_if.assert_nothing_captured()

    def test_timeout_inline(self):
        """timeout (inline)"""

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

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

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

        packets = self.dst_if.get_capture(
            len(self.pkt_infos) - len(dropped_packet_indexes)
        )
        self.verify_capture(packets, dropped_packet_indexes)
        pkts = self.src_if._get_capture(1)
        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.virtual_sleep(0.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(packets, dropped_packet_indexes)
        pkts = self.src_if._get_capture(1)
        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_disabled(self):
        """reassembly disabled"""

        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=1000,
            max_reassemblies=0,
            max_reassembly_length=3,
            expire_walk_interval_ms=10000,
            is_ip6=1,
        )

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

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

    def test_missing_upper(self):
        """missing upper layer"""
        optdata = "\x00" * 100
        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)
            / IPv6ExtHdrFragment(m=1)
            / IPv6ExtHdrDestOpt(
                nh=17, options=PadN(optdata="\101" * 255) / PadN(optdata="\102" * 255)
            )
        )

        self.pg_enable_capture()
        self.src_if.add_stream([p])
        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_truncated_fragment(self):
        """truncated fragment"""
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44, plen=2)
            / IPv6ExtHdrFragment(nh=6)
        )

        self.send_and_assert_no_replies(self.pg0, [pkt], self.pg0)

    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")

    def test_atomic_fragment(self):
        """IPv6 atomic fragment"""
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44, plen=65535)
            / IPv6ExtHdrFragment(
                offset=8191, m=1, res1=0xFF, res2=0xFF, nh=255, id=0xFFFF
            )
            / ("X" * 1452)
        )

        rx = self.send_and_expect(self.pg0, [pkt], self.pg0)
        self.assertIn(ICMPv6ParamProblem, rx[0])

    def test_truncated_fragment(self):
        """IPv6 truncated fragment header"""
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44, plen=2)
            / IPv6ExtHdrFragment(nh=6)
        )

        self.send_and_assert_no_replies(self.pg0, [pkt])

        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6)
            / ICMPv6EchoRequest()
        )
        rx = self.send_and_expect(self.pg0, [pkt], self.pg0)

    def test_one_fragment(self):
        """whole packet in one fragment processed independently"""
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
            / ICMPv6EchoRequest()
            / Raw("X" * 1600)
        )
        frags = fragment_rfc8200(pkt, 1, 400)

        # send a fragment with known id
        self.send_and_assert_no_replies(self.pg0, [frags[0]])

        # send an atomic fragment with same id - should be reassembled
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
            / IPv6ExtHdrFragment(id=1)
            / ICMPv6EchoRequest()
        )
        rx = self.send_and_expect(self.pg0, [pkt], self.pg0)
        self.assertNotIn(IPv6ExtHdrFragment, rx)

        # now finish the original reassembly, this should still be possible
        rx = self.send_and_expect(self.pg0, frags[1:], self.pg0, n_rx=1)
        self.assertNotIn(IPv6ExtHdrFragment, rx)

    def test_bunch_of_fragments(self):
        """valid fragments followed by rogue fragments and atomic fragment"""
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
            / ICMPv6EchoRequest()
            / Raw("X" * 1600)
        )
        frags = fragment_rfc8200(pkt, 1, 400)
        self.send_and_expect(self.pg0, frags, self.pg0, n_rx=1)

        inc_frag = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
            / IPv6ExtHdrFragment(id=1, nh=58, offset=608)
            / Raw("X" * 308)
        )

        self.send_and_assert_no_replies(self.pg0, inc_frag * 604)

        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
            / IPv6ExtHdrFragment(id=1)
            / ICMPv6EchoRequest()
        )
        rx = self.send_and_expect(self.pg0, [pkt], self.pg0)
        self.assertNotIn(IPv6ExtHdrFragment, rx)

    def test_local_enable_disable(self):
        """local reassembly enabled/disable"""
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index, enable_ip6=False
        )
        self.vapi.ip_local_reass_enable_disable(enable_ip6=True)
        pkt = (
            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
            / IPv6(src=self.src_if.remote_ip6, dst=self.src_if.local_ip6)
            / ICMPv6EchoRequest(id=1234)
            / Raw("X" * 1600)
        )
        frags = fragment_rfc8200(pkt, 1, 400)
        r = self.send_and_expect(self.src_if, frags, self.src_if, n_rx=1)[0]
        self.assertEqual(1234, r[ICMPv6EchoReply].id)
        self.vapi.ip_local_reass_enable_disable()

        self.send_and_assert_no_replies(self.src_if, frags)
        self.vapi.ip_local_reass_enable_disable(enable_ip6=True)


class TestIPv6MWReassembly(VppTestCase):
    """IPv6 Reassembly (multiple workers)"""

    vpp_worker_count = 3

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

        cls.create_pg_interfaces(range(cls.vpp_worker_count + 1))
        cls.src_if = cls.pg0
        cls.send_ifs = cls.pg_interfaces[:-1]
        cls.dst_if = cls.pg_interfaces[-1]

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

        # packets sizes reduced here because we are generating packets without
        # Ethernet headers, which are added later (diff fragments go via
        # different interfaces)
        cls.packet_sizes = [
            64 - len(Ether()),
            512 - len(Ether()),
            1518 - len(Ether()),
            9018 - len(Ether()),
        ]
        cls.padding = " abcdefghijklmn"
        cls.create_stream(cls.packet_sizes)
        cls.create_fragments()

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

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().setUp()
        for intf in self.send_ifs:
            self.vapi.ip_reassembly_enable_disable(
                sw_if_index=intf.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.virtual_sleep(0.25)
        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            expire_walk_interval_ms=1000,
            is_ip6=1,
        )

    def tearDown(self):
        for intf in self.send_ifs:
            self.vapi.ip_reassembly_enable_disable(
                sw_if_index=intf.sw_if_index, enable_ip6=False
            )
        super().tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip6-full-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 = (
                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 infos.items():
            p = info.data
            # cls.logger.debug(ppp("Packet:",
            #                      p.__class__(scapy.compat.raw(p))))
            fragments_400 = fragment_rfc8200(p, index, 400)
            cls.pkt_infos.append((index, fragments_400))
        cls.fragments_400 = [x for (_, frags) in cls.pkt_infos for x in frags]
        cls.logger.debug(
            "Fragmented %s packets into %s 400-byte fragments, "
            % (len(infos), len(cls.fragments_400))
        )

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

        :param list capture: Captured packet stream.
        """
        info = None
        seen = set()
        for packet in capture:
            try:
                self.logger.debug(ppp("Got packet:", packet))
                ip = packet[IPv6]
                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[IPv6].src)
                self.assertEqual(ip.dst, saved_packet[IPv6].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 send_packets(self, packets):
        for counter in range(self.vpp_worker_count):
            if 0 == len(packets[counter]):
                continue
            send_if = self.send_ifs[counter]
            send_if.add_stream(
                (
                    Ether(dst=send_if.local_mac, src=send_if.remote_mac) / x
                    for x in packets[counter]
                ),
                worker=counter,
            )
        self.pg_start()

    def test_worker_conflict(self):
        """1st and FO=0 fragments on different workers"""

        # in first wave we send fragments which don't start at offset 0
        # then we send fragments with offset 0 on a different thread
        # then the rest of packets on a random thread
        first_packets = [[] for n in range(self.vpp_worker_count)]
        second_packets = [[] for n in range(self.vpp_worker_count)]
        rest_of_packets = [[] for n in range(self.vpp_worker_count)]
        for _, p in self.pkt_infos:
            wi = randrange(self.vpp_worker_count)
            second_packets[wi].append(p[0])
            if len(p) <= 1:
                continue
            wi2 = wi
            while wi2 == wi:
                wi2 = randrange(self.vpp_worker_count)
            first_packets[wi2].append(p[1])
            wi3 = randrange(self.vpp_worker_count)
            rest_of_packets[wi3].extend(p[2:])

        self.pg_enable_capture()
        self.send_packets(first_packets)
        self.send_packets(second_packets)
        self.send_packets(rest_of_packets)

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)
        for send_if in self.send_ifs:
            send_if.assert_nothing_captured()

        self.logger.debug(self.vapi.ppcli("show trace"))
        self.logger.debug(self.vapi.ppcli("show ip6-full-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.vapi.cli("clear trace")

        self.pg_enable_capture()
        self.send_packets(first_packets)
        self.send_packets(second_packets)
        self.send_packets(rest_of_packets)

        packets = self.dst_if.get_capture(len(self.pkt_infos))
        self.verify_capture(packets)
        for send_if in self.send_ifs:
            send_if.assert_nothing_captured()


class TestIPv6SVReassembly(VppTestCase):
    """IPv6 Shallow Virtual Reassembly"""

    @classmethod
    def setUpClass(cls):
        super().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()

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().setUp()
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.src_if.sw_if_index,
            enable_ip6=True,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
        )
        self.vapi.ip_reassembly_set(
            timeout_ms=0,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
            expire_walk_interval_ms=10,
            is_ip6=1,
        )
        self.virtual_sleep(0.25)
        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
            expire_walk_interval_ms=10000,
            is_ip6=1,
        )

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

    def test_basic(self):
        """basic reassembly"""
        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 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(payload)
        )
        fragments = fragment_rfc8200(p, 1, payload_len / 4)

        # send fragment #2 - should be cached inside reassembly
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[1])
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip6-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        self.dst_if.assert_nothing_captured()

        # send fragment #1 - reassembly is finished now and both fragments
        # forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[0])
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip6-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        c = self.dst_if.get_capture(2)
        for sent, recvd in zip([fragments[1], fragments[0]], c):
            self.assertEqual(sent[IPv6].src, recvd[IPv6].src)
            self.assertEqual(sent[IPv6].dst, recvd[IPv6].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

        # send rest of fragments - should be immediately forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[2:])
        self.pg_start()
        c = self.dst_if.get_capture(len(fragments[2:]))
        for sent, recvd in zip(fragments[2:], c):
            self.assertEqual(sent[IPv6].src, recvd[IPv6].src)
            self.assertEqual(sent[IPv6].dst, recvd[IPv6].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

    def test_verify_clear_trace_mid_reassembly(self):
        """verify clear trace works mid-reassembly"""
        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 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(payload)
        )
        fragments = fragment_rfc8200(p, 1, payload_len / 4)

        self.pg_enable_capture()
        self.src_if.add_stream(fragments[1])
        self.pg_start()

        self.logger.debug(self.vapi.cli("show trace"))
        self.vapi.cli("clear trace")

        self.pg_enable_capture()
        self.src_if.add_stream(fragments[0])
        self.pg_start()
        self.dst_if.get_capture(2)

        self.logger.debug(self.vapi.cli("show trace"))
        self.vapi.cli("clear trace")

        self.pg_enable_capture()
        self.src_if.add_stream(fragments[2:])
        self.pg_start()
        self.dst_if.get_capture(len(fragments[2:]))

    def test_timeout(self):
        """reassembly timeout"""
        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 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(payload)
        )
        fragments = fragment_rfc8200(p, 1, payload_len / 4)

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

        # send fragments #2 and #1 - should be forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[0:2])
        self.pg_start()
        self.logger.debug(self.vapi.ppcli("show ip4-sv-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show buffers"))
        self.logger.debug(self.vapi.ppcli("show trace"))
        c = self.dst_if.get_capture(2)
        for sent, recvd in zip([fragments[1], fragments[0]], c):
            self.assertEqual(sent[IPv6].src, recvd[IPv6].src)
            self.assertEqual(sent[IPv6].dst, recvd[IPv6].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

        # wait for cleanup
        self.virtual_sleep(0.25, "wait before sending rest of fragments")

        # send rest of fragments - shouldn't be forwarded
        self.pg_enable_capture()
        self.src_if.add_stream(fragments[2:])
        self.pg_start()
        self.dst_if.assert_nothing_captured()

    def test_lru(self):
        """reassembly reuses LRU element"""

        self.vapi.ip_reassembly_set(
            timeout_ms=1000000,
            max_reassemblies=1,
            max_reassembly_length=1000,
            type=VppEnum.vl_api_ip_reass_type_t.IP_REASS_TYPE_SHALLOW_VIRTUAL,
            is_ip6=1,
            expire_walk_interval_ms=10000,
        )

        payload_len = 1000
        payload = ""
        counter = 0
        while len(payload) < payload_len:
            payload += "%u " % counter
            counter += 1

        packet_count = 10

        fragments = [
            f
            for i in range(packet_count)
            for p in (
                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(payload)
            )
            for f in fragment_rfc8200(p, i, payload_len / 4)
        ]

        self.pg_enable_capture()
        self.src_if.add_stream(fragments)
        self.pg_start()
        c = self.dst_if.get_capture(len(fragments))
        for sent, recvd in zip(fragments, c):
            self.assertEqual(sent[IPv6].src, recvd[IPv6].src)
            self.assertEqual(sent[IPv6].dst, recvd[IPv6].dst)
            self.assertEqual(sent[Raw].payload, recvd[Raw].payload)

    def test_one_fragment(self):
        """whole packet in one fragment processed independently"""
        pkt = (
            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
            / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
            / ICMPv6EchoRequest()
            / Raw("X" * 1600)
        )
        frags = fragment_rfc8200(pkt, 1, 400)

        # send a fragment with known id
        self.send_and_expect(self.src_if, [frags[0]], self.dst_if)

        # send an atomic fragment with same id - should be reassembled
        pkt = (
            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
            / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
            / IPv6ExtHdrFragment(id=1)
            / ICMPv6EchoRequest()
        )
        rx = self.send_and_expect(self.src_if, [pkt], self.dst_if)

        # now forward packets matching original reassembly, should still work
        rx = self.send_and_expect(self.src_if, frags[1:], self.dst_if)

    def test_bunch_of_fragments(self):
        """valid fragments followed by rogue fragments and atomic fragment"""
        pkt = (
            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
            / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
            / ICMPv6EchoRequest()
            / Raw("X" * 1600)
        )
        frags = fragment_rfc8200(pkt, 1, 400)
        rx = self.send_and_expect(self.src_if, frags, self.dst_if)

        rogue = (
            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
            / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
            / IPv6ExtHdrFragment(id=1, nh=58, offset=608)
            / Raw("X" * 308)
        )

        self.send_and_expect(self.src_if, rogue * 604, self.dst_if)

        pkt = (
            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
            / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
            / IPv6ExtHdrFragment(id=1)
            / ICMPv6EchoRequest()
        )
        rx = self.send_and_expect(self.src_if, [pkt], self.dst_if)

    def test_truncated_fragment(self):
        """truncated fragment"""
        pkt = (
            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44, plen=2)
            / IPv6ExtHdrFragment(nh=6)
        )

        self.send_and_assert_no_replies(self.pg0, [pkt], self.pg0)


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

    @classmethod
    def setUpClass(cls):
        super().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().tearDownClass()

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().setUp()
        self.vapi.ip_reassembly_set(
            timeout_ms=0,
            max_reassemblies=1000,
            max_reassembly_length=1000,
            expire_walk_interval_ms=10,
        )
        self.virtual_sleep(0.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().tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-full-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 infos.items():
            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().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().tearDownClass()

    def setUp(self):
        """Test setup - force timeout on existing reassemblies"""
        super().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.virtual_sleep(0.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().tearDown()

    def show_commands_at_teardown(self):
        self.logger.debug(self.vapi.ppcli("show ip4-full-reassembly details"))
        self.logger.debug(self.vapi.ppcli("show ip6-full-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 self._packet_infos.items()
            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 self._packet_infos.items()
            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)
