#!/usr/bin/env python3
""" Wg tests """

import datetime
import base64
import os

from hashlib import blake2s
from scapy.packet import Packet
from scapy.packet import Raw
from scapy.layers.l2 import Ether, ARP
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.vxlan import VXLAN
from scapy.contrib.wireguard import (
    Wireguard,
    WireguardResponse,
    WireguardInitiation,
    WireguardTransport,
    WireguardCookieReply,
)
from cryptography.hazmat.primitives.asymmetric.x25519 import (
    X25519PrivateKey,
    X25519PublicKey,
)
from cryptography.hazmat.primitives.serialization import (
    Encoding,
    PrivateFormat,
    PublicFormat,
    NoEncryption,
)
from cryptography.hazmat.primitives.hashes import BLAKE2s, Hash
from cryptography.hazmat.primitives.hmac import HMAC
from cryptography.hazmat.backends import default_backend
from noise.connection import NoiseConnection, Keypair

from Crypto.Cipher import ChaCha20_Poly1305
from Crypto.Random import get_random_bytes

from vpp_ipip_tun_interface import VppIpIpTunInterface
from vpp_interface import VppInterface
from vpp_pg_interface import is_ipv6_misc
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort
from vpp_vxlan_tunnel import VppVxlanTunnel
from vpp_object import VppObject
from vpp_papi import VppEnum
from framework import is_distro_ubuntu2204, is_distro_debian11, tag_fixme_vpp_debug
from framework import VppTestCase
from re import compile
import unittest

""" TestWg is a subclass of  VPPTestCase classes.

Wg test.

"""


def private_key_bytes(k):
    return k.private_bytes(Encoding.Raw, PrivateFormat.Raw, NoEncryption())


def public_key_bytes(k):
    return k.public_bytes(Encoding.Raw, PublicFormat.Raw)


def get_field_bytes(pkt, name):
    fld, val = pkt.getfield_and_val(name)
    return fld.i2m(pkt, val)


class VppWgInterface(VppInterface):
    """
    VPP WireGuard interface
    """

    def __init__(self, test, src, port):
        super(VppWgInterface, self).__init__(test)

        self.port = port
        self.src = src
        self.private_key = X25519PrivateKey.generate()
        self.public_key = self.private_key.public_key()

        # cookie related params
        self.cookie_key = blake2s(b"cookie--" + self.public_key_bytes()).digest()

    def public_key_bytes(self):
        return public_key_bytes(self.public_key)

    def private_key_bytes(self):
        return private_key_bytes(self.private_key)

    def add_vpp_config(self):
        r = self.test.vapi.wireguard_interface_create(
            interface={
                "user_instance": 0xFFFFFFFF,
                "port": self.port,
                "src_ip": self.src,
                "private_key": private_key_bytes(self.private_key),
                "generate_key": False,
            }
        )
        self.set_sw_if_index(r.sw_if_index)
        self.test.registry.register(self, self.test.logger)
        return self

    def remove_vpp_config(self):
        self.test.vapi.wireguard_interface_delete(sw_if_index=self._sw_if_index)

    def query_vpp_config(self):
        ts = self.test.vapi.wireguard_interface_dump(sw_if_index=0xFFFFFFFF)
        for t in ts:
            if (
                t.interface.sw_if_index == self._sw_if_index
                and str(t.interface.src_ip) == self.src
                and t.interface.port == self.port
                and t.interface.private_key == private_key_bytes(self.private_key)
            ):
                return True
        return False

    def want_events(self, peer_index=0xFFFFFFFF):
        self.test.vapi.want_wireguard_peer_events(
            enable_disable=1,
            pid=os.getpid(),
            sw_if_index=self._sw_if_index,
            peer_index=peer_index,
        )

    def wait_events(self, expect, peers, timeout=5):
        for i in range(len(peers)):
            rv = self.test.vapi.wait_for_event(timeout, "wireguard_peer_event")
            self.test.assertEqual(rv.peer_index, peers[i])
            self.test.assertEqual(rv.flags, expect)

    def __str__(self):
        return self.object_id()

    def object_id(self):
        return "wireguard-%d" % self._sw_if_index


NOISE_HANDSHAKE_NAME = b"Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
NOISE_IDENTIFIER_NAME = b"WireGuard v1 zx2c4 Jason@zx2c4.com"

HANDSHAKE_COUNTING_INTERVAL = 0.5
UNDER_LOAD_INTERVAL = 1.0
HANDSHAKE_NUM_PER_PEER_UNTIL_UNDER_LOAD = 40
HANDSHAKE_NUM_BEFORE_RATELIMITING = 5

HANDSHAKE_JITTER = 0.5


class VppWgPeer(VppObject):
    def __init__(self, test, itf, endpoint, port, allowed_ips, persistent_keepalive=15):
        self._test = test
        self.itf = itf
        self.endpoint = endpoint
        self.port = port
        self.allowed_ips = allowed_ips
        self.persistent_keepalive = persistent_keepalive

        # remote peer's public
        self.private_key = X25519PrivateKey.generate()
        self.public_key = self.private_key.public_key()

        # cookie related params
        self.cookie_key = blake2s(b"cookie--" + self.public_key_bytes()).digest()
        self.last_sent_cookie = None
        self.last_mac1 = None
        self.last_received_cookie = None

        self.noise = NoiseConnection.from_name(NOISE_HANDSHAKE_NAME)

    def change_endpoint(self, endpoint, port):
        self.endpoint = endpoint
        self.port = port

    def add_vpp_config(self):
        rv = self._test.vapi.wireguard_peer_add(
            peer={
                "public_key": self.public_key_bytes(),
                "port": self.port,
                "endpoint": self.endpoint,
                "n_allowed_ips": len(self.allowed_ips),
                "allowed_ips": self.allowed_ips,
                "sw_if_index": self.itf.sw_if_index,
                "persistent_keepalive": self.persistent_keepalive,
            }
        )
        self.index = rv.peer_index
        self.receiver_index = self.index + 1
        self._test.registry.register(self, self._test.logger)
        return self

    def remove_vpp_config(self):
        self._test.vapi.wireguard_peer_remove(peer_index=self.index)

    def object_id(self):
        return "wireguard-peer-%s" % self.index

    def public_key_bytes(self):
        return public_key_bytes(self.public_key)

    def query_vpp_config(self):
        peers = self._test.vapi.wireguard_peers_dump()

        for p in peers:
            # "::" endpoint will be returned as "0.0.0.0" in peer's details
            endpoint = "0.0.0.0" if self.endpoint == "::" else self.endpoint
            if (
                p.peer.public_key == self.public_key_bytes()
                and p.peer.port == self.port
                and str(p.peer.endpoint) == endpoint
                and p.peer.sw_if_index == self.itf.sw_if_index
                and len(self.allowed_ips) == p.peer.n_allowed_ips
            ):
                self.allowed_ips.sort()
                p.peer.allowed_ips.sort()

                for a1, a2 in zip(self.allowed_ips, p.peer.allowed_ips):
                    if str(a1) != str(a2):
                        return False
                return True
        return False

    def mk_tunnel_header(self, tx_itf, is_ip6=False):
        if is_ip6 is False:
            return (
                Ether(dst=tx_itf.local_mac, src=tx_itf.remote_mac)
                / IP(src=self.endpoint, dst=self.itf.src)
                / UDP(sport=self.port, dport=self.itf.port)
            )
        else:
            return (
                Ether(dst=tx_itf.local_mac, src=tx_itf.remote_mac)
                / IPv6(src=self.endpoint, dst=self.itf.src)
                / UDP(sport=self.port, dport=self.itf.port)
            )

    def noise_reset(self):
        self.noise = NoiseConnection.from_name(NOISE_HANDSHAKE_NAME)

    def noise_init(self, public_key=None):
        self.noise.set_prologue(NOISE_IDENTIFIER_NAME)
        self.noise.set_psks(psk=bytes(bytearray(32)))

        if not public_key:
            public_key = self.itf.public_key

        # local/this private
        self.noise.set_keypair_from_private_bytes(
            Keypair.STATIC, private_key_bytes(self.private_key)
        )
        # remote's public
        self.noise.set_keypair_from_public_bytes(
            Keypair.REMOTE_STATIC, public_key_bytes(public_key)
        )

        self.noise.start_handshake()

    def mk_cookie(self, p, tx_itf, is_resp=False, is_ip6=False):
        self.verify_header(p, is_ip6)

        wg_pkt = Wireguard(p[Raw])

        if is_resp:
            self._test.assertEqual(wg_pkt[Wireguard].message_type, 2)
            self._test.assertEqual(wg_pkt[Wireguard].reserved_zero, 0)
            self._test.assertEqual(wg_pkt[WireguardResponse].mac2, bytes([0] * 16))
        else:
            self._test.assertEqual(wg_pkt[Wireguard].message_type, 1)
            self._test.assertEqual(wg_pkt[Wireguard].reserved_zero, 0)
            self._test.assertEqual(wg_pkt[WireguardInitiation].mac2, bytes([0] * 16))

        # collect info from wg packet (initiation or response)
        src = get_field_bytes(p[IPv6 if is_ip6 else IP], "src")
        sport = p[UDP].sport.to_bytes(2, byteorder="big")
        if is_resp:
            mac1 = wg_pkt[WireguardResponse].mac1
            sender_index = wg_pkt[WireguardResponse].sender_index
        else:
            mac1 = wg_pkt[WireguardInitiation].mac1
            sender_index = wg_pkt[WireguardInitiation].sender_index

        # make cookie reply
        cookie_reply = Wireguard() / WireguardCookieReply()
        cookie_reply[Wireguard].message_type = 3
        cookie_reply[Wireguard].reserved_zero = 0
        cookie_reply[WireguardCookieReply].receiver_index = sender_index
        nonce = get_random_bytes(24)
        cookie_reply[WireguardCookieReply].nonce = nonce

        # generate cookie data
        changing_secret = get_random_bytes(32)
        self.last_sent_cookie = blake2s(
            src + sport, digest_size=16, key=changing_secret
        ).digest()

        # encrypt cookie data
        cipher = ChaCha20_Poly1305.new(key=self.cookie_key, nonce=nonce)
        cipher.update(mac1)
        ciphertext, tag = cipher.encrypt_and_digest(self.last_sent_cookie)
        cookie_reply[WireguardCookieReply].encrypted_cookie = ciphertext + tag

        # prepare cookie reply to be sent
        cookie_reply = self.mk_tunnel_header(tx_itf, is_ip6) / cookie_reply

        return cookie_reply

    def consume_cookie(self, p, is_ip6=False):
        self.verify_header(p, is_ip6)

        cookie_reply = Wireguard(p[Raw])

        self._test.assertEqual(cookie_reply[Wireguard].message_type, 3)
        self._test.assertEqual(cookie_reply[Wireguard].reserved_zero, 0)
        self._test.assertEqual(
            cookie_reply[WireguardCookieReply].receiver_index, self.receiver_index
        )

        # collect info from cookie reply
        nonce = cookie_reply[WireguardCookieReply].nonce
        encrypted_cookie = cookie_reply[WireguardCookieReply].encrypted_cookie
        ciphertext, tag = encrypted_cookie[:16], encrypted_cookie[16:]

        # decrypt cookie data
        cipher = ChaCha20_Poly1305.new(key=self.itf.cookie_key, nonce=nonce)
        cipher.update(self.last_mac1)
        self.last_received_cookie = cipher.decrypt_and_verify(ciphertext, tag)

    def mk_handshake(self, tx_itf, is_ip6=False, public_key=None):
        self.noise.set_as_initiator()
        self.noise_init(public_key)

        p = Wireguard() / WireguardInitiation()

        p[Wireguard].message_type = 1
        p[Wireguard].reserved_zero = 0
        p[WireguardInitiation].sender_index = self.receiver_index

        # some random data for the message
        #  lifted from the noise protocol's wireguard example
        now = datetime.datetime.now()
        tai = struct.pack(
            "!qi",
            4611686018427387914 + int(now.timestamp()),
            int(now.microsecond * 1e3),
        )
        b = self.noise.write_message(payload=tai)

        # load noise into init message
        p[WireguardInitiation].unencrypted_ephemeral = b[0:32]
        p[WireguardInitiation].encrypted_static = b[32:80]
        p[WireguardInitiation].encrypted_timestamp = b[80:108]

        # generate the mac1 hash
        mac_key = blake2s(b"mac1----" + self.itf.public_key_bytes()).digest()
        mac1 = blake2s(bytes(p)[0:116], digest_size=16, key=mac_key).digest()
        p[WireguardInitiation].mac1 = mac1
        self.last_mac1 = mac1

        # generate the mac2 hash
        if self.last_received_cookie:
            mac2 = blake2s(
                bytes(p)[0:132], digest_size=16, key=self.last_received_cookie
            ).digest()
            p[WireguardInitiation].mac2 = mac2
            self.last_received_cookie = None
        else:
            p[WireguardInitiation].mac2 = bytearray(16)

        p = self.mk_tunnel_header(tx_itf, is_ip6) / p

        return p

    def verify_header(self, p, is_ip6=False):
        if is_ip6 is False:
            self._test.assertEqual(p[IP].src, self.itf.src)
            self._test.assertEqual(p[IP].dst, self.endpoint)
            self._test.assert_packet_checksums_valid(p)
        else:
            self._test.assertEqual(p[IPv6].src, self.itf.src)
            self._test.assertEqual(p[IPv6].dst, self.endpoint)
            self._test.assert_packet_checksums_valid(p, False)
        self._test.assertEqual(p[UDP].sport, self.itf.port)
        self._test.assertEqual(p[UDP].dport, self.port)

    def consume_init(self, p, tx_itf, is_ip6=False, is_mac2=False):
        self.noise.set_as_responder()
        self.noise_init(self.itf.public_key)
        self.verify_header(p, is_ip6)

        init = Wireguard(p[Raw])

        self._test.assertEqual(init[Wireguard].message_type, 1)
        self._test.assertEqual(init[Wireguard].reserved_zero, 0)

        self.sender = init[WireguardInitiation].sender_index

        # validate the mac1 hash
        mac_key = blake2s(b"mac1----" + public_key_bytes(self.public_key)).digest()
        mac1 = blake2s(bytes(init)[0:-32], digest_size=16, key=mac_key).digest()
        self._test.assertEqual(init[WireguardInitiation].mac1, mac1)

        # validate the mac2 hash
        if is_mac2:
            self._test.assertNotEqual(init[WireguardInitiation].mac2, bytes([0] * 16))
            self._test.assertNotEqual(self.last_sent_cookie, None)
            mac2 = blake2s(
                bytes(init)[0:-16], digest_size=16, key=self.last_sent_cookie
            ).digest()
            self._test.assertEqual(init[WireguardInitiation].mac2, mac2)
            self.last_sent_cookie = None
        else:
            self._test.assertEqual(init[WireguardInitiation].mac2, bytes([0] * 16))

        # this passes only unencrypted_ephemeral, encrypted_static,
        # encrypted_timestamp fields of the init
        payload = self.noise.read_message(bytes(init)[8:-32])

        # build the response
        b = self.noise.write_message()
        mac_key = blake2s(b"mac1----" + public_key_bytes(self.itf.public_key)).digest()
        resp = Wireguard(message_type=2, reserved_zero=0) / WireguardResponse(
            sender_index=self.receiver_index,
            receiver_index=self.sender,
            unencrypted_ephemeral=b[0:32],
            encrypted_nothing=b[32:],
        )
        mac1 = blake2s(bytes(resp)[:-32], digest_size=16, key=mac_key).digest()
        resp[WireguardResponse].mac1 = mac1
        self.last_mac1 = mac1

        resp = self.mk_tunnel_header(tx_itf, is_ip6) / resp
        self._test.assertTrue(self.noise.handshake_finished)

        return resp

    def consume_response(self, p, is_ip6=False):
        self.verify_header(p, is_ip6)

        resp = Wireguard(p[Raw])

        self._test.assertEqual(resp[Wireguard].message_type, 2)
        self._test.assertEqual(resp[Wireguard].reserved_zero, 0)
        self._test.assertEqual(
            resp[WireguardResponse].receiver_index, self.receiver_index
        )

        self.sender = resp[Wireguard].sender_index

        payload = self.noise.read_message(bytes(resp)[12:60])
        self._test.assertEqual(payload, b"")
        self._test.assertTrue(self.noise.handshake_finished)

    def decrypt_transport(self, p, is_ip6=False):
        self.verify_header(p, is_ip6)

        p = Wireguard(p[Raw])
        self._test.assertEqual(p[Wireguard].message_type, 4)
        self._test.assertEqual(p[Wireguard].reserved_zero, 0)
        self._test.assertEqual(
            p[WireguardTransport].receiver_index, self.receiver_index
        )

        d = self.noise.decrypt(p[WireguardTransport].encrypted_encapsulated_packet)
        return d

    def encrypt_transport(self, p):
        return self.noise.encrypt(bytes(p))

    def validate_encapped(self, rxs, tx, is_tunnel_ip6=False, is_transport_ip6=False):
        ret_rxs = []
        for rx in rxs:
            rx = self.decrypt_transport(rx, is_tunnel_ip6)
            if is_transport_ip6 is False:
                rx = IP(rx)
                # check the original packet is present
                self._test.assertEqual(rx[IP].dst, tx[IP].dst)
                self._test.assertEqual(rx[IP].ttl, tx[IP].ttl - 1)
            else:
                rx = IPv6(rx)
                # check the original packet is present
                self._test.assertEqual(rx[IPv6].dst, tx[IPv6].dst)
                self._test.assertEqual(rx[IPv6].hlim, tx[IPv6].hlim - 1)
            ret_rxs.append(rx)
        return ret_rxs

    def want_events(self):
        self._test.vapi.want_wireguard_peer_events(
            enable_disable=1,
            pid=os.getpid(),
            peer_index=self.index,
            sw_if_index=self.itf.sw_if_index,
        )

    def wait_event(self, expect, timeout=5):
        rv = self._test.vapi.wait_for_event(timeout, "wireguard_peer_event")
        self._test.assertEqual(rv.flags, expect)
        self._test.assertEqual(rv.peer_index, self.index)


def is_handshake_init(p):
    wg_p = Wireguard(p[Raw])

    return wg_p[Wireguard].message_type == 1


class TestWg(VppTestCase):
    """Wireguard Test Case"""

    error_str = compile(r"Error")

    wg4_output_node_name = "/err/wg4-output-tun/"
    wg4_input_node_name = "/err/wg4-input/"
    wg6_output_node_name = "/err/wg6-output-tun/"
    wg6_input_node_name = "/err/wg6-input/"
    kp4_error = wg4_output_node_name + "Keypair error"
    mac4_error = wg4_input_node_name + "Invalid MAC handshake"
    peer4_in_err = wg4_input_node_name + "Peer error"
    peer4_out_err = wg4_output_node_name + "Peer error"
    kp6_error = wg6_output_node_name + "Keypair error"
    mac6_error = wg6_input_node_name + "Invalid MAC handshake"
    peer6_in_err = wg6_input_node_name + "Peer error"
    peer6_out_err = wg6_output_node_name + "Peer error"
    cookie_dec4_err = wg4_input_node_name + "Failed during Cookie decryption"
    cookie_dec6_err = wg6_input_node_name + "Failed during Cookie decryption"
    ratelimited4_err = wg4_input_node_name + "Handshake ratelimited"
    ratelimited6_err = wg6_input_node_name + "Handshake ratelimited"

    @classmethod
    def setUpClass(cls):
        super(TestWg, cls).setUpClass()
        if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
            cls, "vpp"
        ):
            return
        try:
            cls.create_pg_interfaces(range(3))
            for i in cls.pg_interfaces:
                i.admin_up()
                i.config_ip4()
                i.config_ip6()
                i.resolve_arp()
                i.resolve_ndp()

        except Exception:
            super(TestWg, cls).tearDownClass()
            raise

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

    def setUp(self):
        super(VppTestCase, self).setUp()
        self.base_kp4_err = self.statistics.get_err_counter(self.kp4_error)
        self.base_mac4_err = self.statistics.get_err_counter(self.mac4_error)
        self.base_peer4_in_err = self.statistics.get_err_counter(self.peer4_in_err)
        self.base_peer4_out_err = self.statistics.get_err_counter(self.peer4_out_err)
        self.base_kp6_err = self.statistics.get_err_counter(self.kp6_error)
        self.base_mac6_err = self.statistics.get_err_counter(self.mac6_error)
        self.base_peer6_in_err = self.statistics.get_err_counter(self.peer6_in_err)
        self.base_peer6_out_err = self.statistics.get_err_counter(self.peer6_out_err)
        self.base_cookie_dec4_err = self.statistics.get_err_counter(
            self.cookie_dec4_err
        )
        self.base_cookie_dec6_err = self.statistics.get_err_counter(
            self.cookie_dec6_err
        )
        self.base_ratelimited4_err = self.statistics.get_err_counter(
            self.ratelimited4_err
        )
        self.base_ratelimited6_err = self.statistics.get_err_counter(
            self.ratelimited6_err
        )

    def send_and_assert_no_replies_ignoring_init(
        self, intf, pkts, remark="", timeout=None
    ):
        self.pg_send(intf, pkts)

        def _filter_out_fn(p):
            return is_ipv6_misc(p) or is_handshake_init(p)

        try:
            if not timeout:
                timeout = 1
            for i in self.pg_interfaces:
                i.assert_nothing_captured(
                    timeout=timeout, remark=remark, filter_out_fn=_filter_out_fn
                )
                timeout = 0.1
        finally:
            pass

    def test_wg_interface(self):
        """Simple interface creation"""
        port = 12312

        # Create interface
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()

        self.logger.info(self.vapi.cli("sh int"))

        # delete interface
        wg0.remove_vpp_config()

    def test_handshake_hash(self):
        """test hashing an init message"""
        # a init packet generated by linux given the key below
        h = (
            "0100000098b9032b"
            "55cc4b39e73c3d24"
            "a2a1ab884b524a81"
            "1808bb86640fb70d"
            "e93154fec1879125"
            "ab012624a27f0b75"
            "c0a2582f438ddb5f"
            "8e768af40b4ab444"
            "02f9ff473e1b797e"
            "80d39d93c5480c82"
            "a3d4510f70396976"
            "586fb67300a5167b"
            "ae6ca3ff3dfd00eb"
            "59be198810f5aa03"
            "6abc243d2155ee4f"
            "2336483900aef801"
            "08752cd700000000"
            "0000000000000000"
            "00000000"
        )

        b = bytearray.fromhex(h)
        tgt = Wireguard(b)

        pubb = base64.b64decode("aRuHFTTxICIQNefp05oKWlJv3zgKxb8+WW7JJMh0jyM=")
        pub = X25519PublicKey.from_public_bytes(pubb)

        self.assertEqual(pubb, public_key_bytes(pub))

        # strip the macs and build a new packet
        init = b[0:-32]
        mac_key = blake2s(b"mac1----" + public_key_bytes(pub)).digest()
        init += blake2s(init, digest_size=16, key=mac_key).digest()
        init += b"\x00" * 16

        act = Wireguard(init)

        self.assertEqual(tgt, act)

    def _test_wg_send_cookie_tmpl(self, is_resp, is_ip6):
        port = 12323

        # create wg interface
        if is_ip6:
            wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip6()
        else:
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()

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

        # create a peer
        if is_ip6:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip6, port + 1, ["1::3:0/112"]
            ).add_vpp_config()
        else:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
            ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        if is_resp:
            # skip the first automatic handshake
            self.pg1.get_capture(1, timeout=HANDSHAKE_JITTER)

            # prepare and send a handshake initiation
            # expect the peer to send a handshake response
            init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
            rxs = self.send_and_expect(self.pg1, [init], self.pg1)
        else:
            # wait for the peer to send a handshake initiation
            rxs = self.pg1.get_capture(1, timeout=2)

        # prepare and send a wrong cookie reply
        # expect no replies and the cookie error incremented
        cookie = peer_1.mk_cookie(rxs[0], self.pg1, is_resp=is_resp, is_ip6=is_ip6)
        cookie.nonce = b"1234567890"
        self.send_and_assert_no_replies(self.pg1, [cookie], timeout=0.1)
        if is_ip6:
            self.assertEqual(
                self.base_cookie_dec6_err + 1,
                self.statistics.get_err_counter(self.cookie_dec6_err),
            )
        else:
            self.assertEqual(
                self.base_cookie_dec4_err + 1,
                self.statistics.get_err_counter(self.cookie_dec4_err),
            )

        # prepare and send a correct cookie reply
        cookie = peer_1.mk_cookie(rxs[0], self.pg1, is_resp=is_resp, is_ip6=is_ip6)
        self.pg_send(self.pg1, [cookie])

        # wait for the peer to send a handshake initiation with mac2 set
        rxs = self.pg1.get_capture(1, timeout=6)

        # verify the initiation and its mac2
        peer_1.consume_init(rxs[0], self.pg1, is_ip6=is_ip6, is_mac2=True)

        # remove configs
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_send_cookie_on_init_v4(self):
        """Send cookie on handshake initiation (v4)"""
        self._test_wg_send_cookie_tmpl(is_resp=False, is_ip6=False)

    def test_wg_send_cookie_on_init_v6(self):
        """Send cookie on handshake initiation (v6)"""
        self._test_wg_send_cookie_tmpl(is_resp=False, is_ip6=True)

    def test_wg_send_cookie_on_resp_v4(self):
        """Send cookie on handshake response (v4)"""
        self._test_wg_send_cookie_tmpl(is_resp=True, is_ip6=False)

    def test_wg_send_cookie_on_resp_v6(self):
        """Send cookie on handshake response (v6)"""
        self._test_wg_send_cookie_tmpl(is_resp=True, is_ip6=True)

    def _test_wg_receive_cookie_tmpl(self, is_resp, is_ip6):
        port = 12323

        # create wg interface
        if is_ip6:
            wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip6()
        else:
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()

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

        # create a peer
        if is_ip6:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip6, port + 1, ["1::3:0/112"]
            ).add_vpp_config()
        else:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
            ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        if is_resp:
            # wait for the peer to send a handshake initiation
            rxs = self.pg1.get_capture(1, timeout=2)
            # prepare and send a bunch of handshake responses
            # expect to switch to under load state
            resp = peer_1.consume_init(rxs[0], self.pg1, is_ip6=is_ip6)
            txs = [resp] * HANDSHAKE_NUM_PER_PEER_UNTIL_UNDER_LOAD
            rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)
            # reset noise to be able to turn into initiator later
            peer_1.noise_reset()
        else:
            # skip the first automatic handshake
            self.pg1.get_capture(1, timeout=HANDSHAKE_JITTER)

            # prepare and send a bunch of handshake initiations
            # expect to switch to under load state
            init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
            txs = [init] * HANDSHAKE_NUM_PER_PEER_UNTIL_UNDER_LOAD
            rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        # expect the peer to send a cookie reply
        peer_1.consume_cookie(rxs[-1], is_ip6=is_ip6)

        # prepare and send a handshake initiation with wrong mac2
        # expect a cookie reply
        init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
        init.mac2 = b"1234567890"
        rxs = self.send_and_expect(self.pg1, [init], self.pg1)
        peer_1.consume_cookie(rxs[0], is_ip6=is_ip6)

        # prepare and send a handshake initiation with correct mac2
        # expect a handshake response
        init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
        rxs = self.send_and_expect(self.pg1, [init], self.pg1)

        # verify the response
        peer_1.consume_response(rxs[0], is_ip6=is_ip6)

        # clear up under load state
        self.sleep(UNDER_LOAD_INTERVAL)

        # remove configs
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_receive_cookie_on_init_v4(self):
        """Receive cookie on handshake initiation (v4)"""
        self._test_wg_receive_cookie_tmpl(is_resp=False, is_ip6=False)

    def test_wg_receive_cookie_on_init_v6(self):
        """Receive cookie on handshake initiation (v6)"""
        self._test_wg_receive_cookie_tmpl(is_resp=False, is_ip6=True)

    def test_wg_receive_cookie_on_resp_v4(self):
        """Receive cookie on handshake response (v4)"""
        self._test_wg_receive_cookie_tmpl(is_resp=True, is_ip6=False)

    def test_wg_receive_cookie_on_resp_v6(self):
        """Receive cookie on handshake response (v6)"""
        self._test_wg_receive_cookie_tmpl(is_resp=True, is_ip6=True)

    def test_wg_under_load_interval(self):
        """Under load interval"""
        port = 12323

        # create wg interface
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        # create a peer
        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # skip the first automatic handshake
        self.pg1.get_capture(1, timeout=HANDSHAKE_JITTER)

        # prepare and send a bunch of handshake initiations
        # expect to switch to under load state
        init = peer_1.mk_handshake(self.pg1)
        txs = [init] * HANDSHAKE_NUM_PER_PEER_UNTIL_UNDER_LOAD
        rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        # expect the peer to send a cookie reply
        peer_1.consume_cookie(rxs[-1])

        # sleep till the next counting interval
        # expect under load state is still active
        self.sleep(HANDSHAKE_COUNTING_INTERVAL)

        # prepare and send a handshake initiation with wrong mac2
        # expect a cookie reply
        init = peer_1.mk_handshake(self.pg1)
        init.mac2 = b"1234567890"
        rxs = self.send_and_expect(self.pg1, [init], self.pg1)
        peer_1.consume_cookie(rxs[0])

        # sleep till the end of being under load
        # expect under load state is over
        self.sleep(UNDER_LOAD_INTERVAL - HANDSHAKE_COUNTING_INTERVAL)

        # prepare and send a handshake initiation with wrong mac2
        # expect a handshake response
        init = peer_1.mk_handshake(self.pg1)
        init.mac2 = b"1234567890"
        rxs = self.send_and_expect(self.pg1, [init], self.pg1)

        # verify the response
        peer_1.consume_response(rxs[0])

        # remove configs
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def _test_wg_handshake_ratelimiting_tmpl(self, is_ip6):
        port = 12323

        # create wg interface
        if is_ip6:
            wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip6()
        else:
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()

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

        # create a peer
        if is_ip6:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip6, port + 1, ["1::3:0/112"]
            ).add_vpp_config()
        else:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
            ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # skip the first automatic handshake
        self.pg1.get_capture(1, timeout=HANDSHAKE_JITTER)

        # prepare and send a bunch of handshake initiations
        # expect to switch to under load state
        init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
        txs = [init] * HANDSHAKE_NUM_PER_PEER_UNTIL_UNDER_LOAD
        rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        # expect the peer to send a cookie reply
        peer_1.consume_cookie(rxs[-1], is_ip6=is_ip6)

        # prepare and send a bunch of handshake initiations with correct mac2
        # expect a handshake response and then ratelimiting
        NUM_TO_REJECT = 10
        init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
        txs = [init] * (HANDSHAKE_NUM_BEFORE_RATELIMITING + NUM_TO_REJECT)
        rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        if is_ip6:
            self.assertEqual(
                self.base_ratelimited6_err + NUM_TO_REJECT,
                self.statistics.get_err_counter(self.ratelimited6_err),
            )
        else:
            self.assertEqual(
                self.base_ratelimited4_err + NUM_TO_REJECT,
                self.statistics.get_err_counter(self.ratelimited4_err),
            )

        # verify the response
        peer_1.consume_response(rxs[0], is_ip6=is_ip6)

        # clear up under load state
        self.sleep(UNDER_LOAD_INTERVAL)

        # remove configs
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_handshake_ratelimiting_v4(self):
        """Handshake ratelimiting (v4)"""
        self._test_wg_handshake_ratelimiting_tmpl(is_ip6=False)

    def test_wg_handshake_ratelimiting_v6(self):
        """Handshake ratelimiting (v6)"""
        self._test_wg_handshake_ratelimiting_tmpl(is_ip6=True)

    def test_wg_handshake_ratelimiting_multi_peer(self):
        """Handshake ratelimiting (multiple peer)"""
        port = 12323

        # create wg interface
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        # create two peers
        NUM_PEERS = 2
        self.pg1.generate_remote_hosts(NUM_PEERS)
        self.pg1.configure_ipv4_neighbors()

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_hosts[0].ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        peer_2 = VppWgPeer(
            self, wg0, self.pg1.remote_hosts[1].ip4, port + 1, ["10.11.4.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 2)

        # skip the first automatic handshake
        self.pg1.get_capture(NUM_PEERS, timeout=HANDSHAKE_JITTER)

        # (peer_1) prepare and send a bunch of handshake initiations
        # expect not to switch to under load state
        init_1 = peer_1.mk_handshake(self.pg1)
        txs = [init_1] * HANDSHAKE_NUM_PER_PEER_UNTIL_UNDER_LOAD
        rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        # (peer_1) expect the peer to send a handshake response
        peer_1.consume_response(rxs[0])
        peer_1.noise_reset()

        # (peer_1) send another bunch of handshake initiations
        # expect to switch to under load state
        rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        # (peer_1) expect the peer to send a cookie reply
        peer_1.consume_cookie(rxs[-1])

        # (peer_2) prepare and send a handshake initiation
        # expect a cookie reply
        init_2 = peer_2.mk_handshake(self.pg1)
        rxs = self.send_and_expect(self.pg1, [init_2], self.pg1)
        peer_2.consume_cookie(rxs[0])

        # (peer_1) (peer_2) prepare and send a bunch of handshake initiations with correct mac2
        # expect a handshake response and then ratelimiting
        PEER_1_NUM_TO_REJECT = 2
        PEER_2_NUM_TO_REJECT = 5
        init_1 = peer_1.mk_handshake(self.pg1)
        txs = [init_1] * (HANDSHAKE_NUM_BEFORE_RATELIMITING + PEER_1_NUM_TO_REJECT)
        init_2 = peer_2.mk_handshake(self.pg1)
        txs += [init_2] * (HANDSHAKE_NUM_BEFORE_RATELIMITING + PEER_2_NUM_TO_REJECT)
        rxs = self.send_and_expect_some(self.pg1, txs, self.pg1)

        self.assertTrue(
            self.base_ratelimited4_err + PEER_1_NUM_TO_REJECT
            < self.statistics.get_err_counter(self.ratelimited4_err)
            <= self.base_ratelimited4_err + PEER_1_NUM_TO_REJECT + PEER_2_NUM_TO_REJECT
        )

        # (peer_1) (peer_2) verify the response
        peer_1.consume_response(rxs[0])
        peer_2.consume_response(rxs[1])

        # clear up under load state
        self.sleep(UNDER_LOAD_INTERVAL)

        # remove configs
        peer_1.remove_vpp_config()
        peer_2.remove_vpp_config()
        wg0.remove_vpp_config()

    def _test_wg_peer_roaming_on_handshake_tmpl(self, is_endpoint_set, is_resp, is_ip6):
        port = 12323

        # create wg interface
        if is_ip6:
            wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip6()
        else:
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()

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

        # create more remote hosts
        NUM_REMOTE_HOSTS = 2
        self.pg1.generate_remote_hosts(NUM_REMOTE_HOSTS)
        if is_ip6:
            self.pg1.configure_ipv6_neighbors()
        else:
            self.pg1.configure_ipv4_neighbors()

        # create a peer
        if is_ip6:
            peer_1 = VppWgPeer(
                test=self,
                itf=wg0,
                endpoint=self.pg1.remote_hosts[0].ip6 if is_endpoint_set else "::",
                port=port + 1 if is_endpoint_set else 0,
                allowed_ips=["1::3:0/112"],
            ).add_vpp_config()
        else:
            peer_1 = VppWgPeer(
                test=self,
                itf=wg0,
                endpoint=self.pg1.remote_hosts[0].ip4 if is_endpoint_set else "0.0.0.0",
                port=port + 1 if is_endpoint_set else 0,
                allowed_ips=["10.11.3.0/24"],
            ).add_vpp_config()
        self.assertTrue(peer_1.query_vpp_config())

        if is_resp:
            # wait for the peer to send a handshake initiation
            rxs = self.pg1.get_capture(1, timeout=2)
            # prepare a handshake response
            resp = peer_1.consume_init(rxs[0], self.pg1, is_ip6=is_ip6)
            # change endpoint
            if is_ip6:
                peer_1.change_endpoint(self.pg1.remote_hosts[1].ip6, port + 100)
                resp[IPv6].src, resp[UDP].sport = peer_1.endpoint, peer_1.port
            else:
                peer_1.change_endpoint(self.pg1.remote_hosts[1].ip4, port + 100)
                resp[IP].src, resp[UDP].sport = peer_1.endpoint, peer_1.port
            # send the handshake response
            # expect a keepalive message sent to the new endpoint
            rxs = self.send_and_expect(self.pg1, [resp], self.pg1)
            # verify the keepalive message
            b = peer_1.decrypt_transport(rxs[0], is_ip6=is_ip6)
            self.assertEqual(0, len(b))
        else:
            # change endpoint
            if is_ip6:
                peer_1.change_endpoint(self.pg1.remote_hosts[1].ip6, port + 100)
            else:
                peer_1.change_endpoint(self.pg1.remote_hosts[1].ip4, port + 100)
            # prepare and send a handshake initiation
            # expect a handshake response sent to the new endpoint
            init = peer_1.mk_handshake(self.pg1, is_ip6=is_ip6)
            rxs = self.send_and_expect(self.pg1, [init], self.pg1)
            # verify the response
            peer_1.consume_response(rxs[0], is_ip6=is_ip6)
        self.assertTrue(peer_1.query_vpp_config())

        # remove configs
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_roaming_on_init_v4(self):
        """Peer roaming on handshake initiation (v4)"""
        self._test_wg_peer_roaming_on_handshake_tmpl(
            is_endpoint_set=False, is_resp=False, is_ip6=False
        )

    def test_wg_peer_roaming_on_init_v6(self):
        """Peer roaming on handshake initiation (v6)"""
        self._test_wg_peer_roaming_on_handshake_tmpl(
            is_endpoint_set=False, is_resp=False, is_ip6=True
        )

    def test_wg_peer_roaming_on_resp_v4(self):
        """Peer roaming on handshake response (v4)"""
        self._test_wg_peer_roaming_on_handshake_tmpl(
            is_endpoint_set=True, is_resp=True, is_ip6=False
        )

    def test_wg_peer_roaming_on_resp_v6(self):
        """Peer roaming on handshake response (v6)"""
        self._test_wg_peer_roaming_on_handshake_tmpl(
            is_endpoint_set=True, is_resp=True, is_ip6=True
        )

    def _test_wg_peer_roaming_on_data_tmpl(self, is_async, is_ip6):
        self.vapi.wg_set_async_mode(is_async)
        port = 12323

        # create wg interface
        if is_ip6:
            wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip6()
        else:
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()

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

        # create more remote hosts
        NUM_REMOTE_HOSTS = 2
        self.pg1.generate_remote_hosts(NUM_REMOTE_HOSTS)
        if is_ip6:
            self.pg1.configure_ipv6_neighbors()
        else:
            self.pg1.configure_ipv4_neighbors()

        # create a peer
        if is_ip6:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_hosts[0].ip6, port + 1, ["1::3:0/112"]
            ).add_vpp_config()
        else:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_hosts[0].ip4, port + 1, ["10.11.3.0/24"]
            ).add_vpp_config()
        self.assertTrue(peer_1.query_vpp_config())

        # create a route to rewrite traffic into the wg interface
        if is_ip6:
            r1 = VppIpRoute(
                self, "1::3:0", 112, [VppRoutePath("1::3:1", wg0.sw_if_index)]
            ).add_vpp_config()
        else:
            r1 = VppIpRoute(
                self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
            ).add_vpp_config()

        # wait for the peer to send a handshake initiation
        rxs = self.pg1.get_capture(1, timeout=2)

        # prepare and send a handshake response
        # expect a keepalive message
        resp = peer_1.consume_init(rxs[0], self.pg1, is_ip6=is_ip6)
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        # verify the keepalive message
        b = peer_1.decrypt_transport(rxs[0], is_ip6=is_ip6)
        self.assertEqual(0, len(b))

        # change endpoint
        if is_ip6:
            peer_1.change_endpoint(self.pg1.remote_hosts[1].ip6, port + 100)
        else:
            peer_1.change_endpoint(self.pg1.remote_hosts[1].ip4, port + 100)

        # prepare and send a data packet
        # expect endpoint change
        if is_ip6:
            ip_header = IPv6(src="1::3:1", dst=self.pg0.remote_ip6, hlim=20)
        else:
            ip_header = IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
        data = (
            peer_1.mk_tunnel_header(self.pg1, is_ip6=is_ip6)
            / Wireguard(message_type=4, reserved_zero=0)
            / WireguardTransport(
                receiver_index=peer_1.sender,
                counter=0,
                encrypted_encapsulated_packet=peer_1.encrypt_transport(
                    ip_header / UDP(sport=222, dport=223) / Raw()
                ),
            )
        )
        rxs = self.send_and_expect(self.pg1, [data], self.pg0)
        if is_ip6:
            self.assertEqual(rxs[0][IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(rxs[0][IPv6].hlim, 19)
        else:
            self.assertEqual(rxs[0][IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rxs[0][IP].ttl, 19)
        self.assertTrue(peer_1.query_vpp_config())

        # prepare and send a packet that will be rewritten into the wg interface
        # expect a data packet sent to the new endpoint
        if is_ip6:
            ip_header = IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
        else:
            ip_header = IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / ip_header
            / UDP(sport=555, dport=556)
            / Raw()
        )
        rxs = self.send_and_expect(self.pg0, [p], self.pg1)

        # verify the data packet
        peer_1.validate_encapped(rxs, p, is_tunnel_ip6=is_ip6, is_transport_ip6=is_ip6)

        # remove configs
        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_roaming_on_data_v4_sync(self):
        """Peer roaming on data packet (v4, sync)"""
        self._test_wg_peer_roaming_on_data_tmpl(is_async=False, is_ip6=False)

    def test_wg_peer_roaming_on_data_v6_sync(self):
        """Peer roaming on data packet (v6, sync)"""
        self._test_wg_peer_roaming_on_data_tmpl(is_async=False, is_ip6=True)

    def test_wg_peer_roaming_on_data_v4_async(self):
        """Peer roaming on data packet (v4, async)"""
        self._test_wg_peer_roaming_on_data_tmpl(is_async=True, is_ip6=False)

    def test_wg_peer_roaming_on_data_v6_async(self):
        """Peer roaming on data packet (v6, async)"""
        self._test_wg_peer_roaming_on_data_tmpl(is_async=True, is_ip6=True)

    def test_wg_peer_resp(self):
        """Send handshake response IPv4 tunnel"""
        port = 12323

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # wait for the peer to send a handshake
        rx = self.pg1.get_capture(1, timeout=2)

        # consume the handshake in the noise protocol and
        # generate the response
        resp = peer_1.consume_init(rx[0], self.pg1)

        # send the response, get keepalive
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        for rx in rxs:
            b = peer_1.decrypt_transport(rx)
            self.assertEqual(0, len(b))

        # send a packets that are routed into the tunnel
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        peer_1.validate_encapped(rxs, p)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_resp_ipv6(self):
        """Send handshake response IPv6 tunnel"""
        port = 12323

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip6, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # wait for the peer to send a handshake
        rx = self.pg1.get_capture(1, timeout=2)

        # consume the handshake in the noise protocol and
        # generate the response
        resp = peer_1.consume_init(rx[0], self.pg1, is_ip6=True)

        # send the response, get keepalive
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        for rx in rxs:
            b = peer_1.decrypt_transport(rx, True)
            self.assertEqual(0, len(b))

        # send a packets that are routed into the tunnel
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )

        rxs = self.send_and_expect(self.pg0, p * 2, self.pg1)
        peer_1.validate_encapped(rxs, p, True)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1, True)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_v4o4(self):
        """Test v4o4"""

        port = 12333

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()
        r2 = VppIpRoute(
            self, "20.22.3.0", 24, [VppRoutePath("20.22.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # route a packet into the wg interface
        #  use the allowed-ip prefix
        #  this is dropped because the peer is not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp4_err + 1, self.statistics.get_err_counter(self.kp4_error)
        )

        # route a packet into the wg interface
        #  use a not allowed-ip prefix
        #  this is dropped because there is no matching peer
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="20.22.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_peer4_out_err + 1,
            self.statistics.get_err_counter(self.peer4_out_err),
        )

        # send a handsake from the peer with an invalid MAC
        p = peer_1.mk_handshake(self.pg1)
        p[WireguardInitiation].mac1 = b"foobar"
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])
        self.assertEqual(
            self.base_mac4_err + 1, self.statistics.get_err_counter(self.mac4_error)
        )

        # send a handsake from the peer but signed by the wrong key.
        p = peer_1.mk_handshake(
            self.pg1, False, X25519PrivateKey.generate().public_key()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])
        self.assertEqual(
            self.base_peer4_in_err + 1,
            self.statistics.get_err_counter(self.peer4_in_err),
        )

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # route a packet into the wg interface
        #  this is dropped because the peer is still not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp4_err + 2, self.statistics.get_err_counter(self.kp4_error)
        )

        # send a data packet from the peer through the tunnel
        # this completes the handshake
        p = (
            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
            / UDP(sport=222, dport=223)
            / Raw()
        )
        d = peer_1.encrypt_transport(p)
        p = peer_1.mk_tunnel_header(self.pg1) / (
            Wireguard(message_type=4, reserved_zero=0)
            / WireguardTransport(
                receiver_index=peer_1.sender, counter=0, encrypted_encapsulated_packet=d
            )
        )
        rxs = self.send_and_expect(self.pg1, [p], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        for rx in rxs:
            rx = IP(peer_1.decrypt_transport(rx))

            # check the original packet is present
            self.assertEqual(rx[IP].dst, p[IP].dst)
            self.assertEqual(rx[IP].ttl, p[IP].ttl - 1)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii + 1,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        r1.remove_vpp_config()
        r2.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_v6o6(self):
        """Test v6o6"""

        port = 12343

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip6()

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip6, port + 1, ["1::3:0/112"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "1::3:0", 112, [VppRoutePath("1::3:1", wg0.sw_if_index)]
        ).add_vpp_config()
        r2 = VppIpRoute(
            self, "22::3:0", 112, [VppRoutePath("22::3:1", wg0.sw_if_index)]
        ).add_vpp_config()

        # route a packet into the wg interface
        #  use the allowed-ip prefix
        #  this is dropped because the peer is not initiated

        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])

        self.assertEqual(
            self.base_kp6_err + 1, self.statistics.get_err_counter(self.kp6_error)
        )

        # route a packet into the wg interface
        #  use a not allowed-ip prefix
        #  this is dropped because there is no matching peer
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="22::3:2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_peer6_out_err + 1,
            self.statistics.get_err_counter(self.peer6_out_err),
        )

        # send a handsake from the peer with an invalid MAC
        p = peer_1.mk_handshake(self.pg1, True)
        p[WireguardInitiation].mac1 = b"foobar"
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])

        self.assertEqual(
            self.base_mac6_err + 1, self.statistics.get_err_counter(self.mac6_error)
        )

        # send a handsake from the peer but signed by the wrong key.
        p = peer_1.mk_handshake(
            self.pg1, True, X25519PrivateKey.generate().public_key()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])
        self.assertEqual(
            self.base_peer6_in_err + 1,
            self.statistics.get_err_counter(self.peer6_in_err),
        )

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1, True)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0], True)

        # route a packet into the wg interface
        #  this is dropped because the peer is still not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp6_err + 2, self.statistics.get_err_counter(self.kp6_error)
        )

        # send a data packet from the peer through the tunnel
        # this completes the handshake
        p = (
            IPv6(src="1::3:1", dst=self.pg0.remote_ip6, hlim=20)
            / UDP(sport=222, dport=223)
            / Raw()
        )
        d = peer_1.encrypt_transport(p)
        p = peer_1.mk_tunnel_header(self.pg1, True) / (
            Wireguard(message_type=4, reserved_zero=0)
            / WireguardTransport(
                receiver_index=peer_1.sender, counter=0, encrypted_encapsulated_packet=d
            )
        )
        rxs = self.send_and_expect(self.pg1, [p], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(rx[IPv6].hlim, 19)

        # send a packets that are routed into the tunnel
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        for rx in rxs:
            rx = IPv6(peer_1.decrypt_transport(rx, True))

            # check the original packet is present
            self.assertEqual(rx[IPv6].dst, p[IPv6].dst)
            self.assertEqual(rx[IPv6].hlim, p[IPv6].hlim - 1)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1, True)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii + 1,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IPv6(src="1::3:1", dst=self.pg0.remote_ip6, hlim=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(rx[IPv6].hlim, 19)

        r1.remove_vpp_config()
        r2.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_v6o4(self):
        """Test v6o4"""

        port = 12353

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip6()

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["1::3:0/112"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "1::3:0", 112, [VppRoutePath("1::3:1", wg0.sw_if_index)]
        ).add_vpp_config()

        # route a packet into the wg interface
        #  use the allowed-ip prefix
        #  this is dropped because the peer is not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp6_err + 1, self.statistics.get_err_counter(self.kp6_error)
        )

        # send a handsake from the peer with an invalid MAC
        p = peer_1.mk_handshake(self.pg1)
        p[WireguardInitiation].mac1 = b"foobar"
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])

        self.assertEqual(
            self.base_mac4_err + 1, self.statistics.get_err_counter(self.mac4_error)
        )

        # send a handsake from the peer but signed by the wrong key.
        p = peer_1.mk_handshake(
            self.pg1, False, X25519PrivateKey.generate().public_key()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])
        self.assertEqual(
            self.base_peer4_in_err + 1,
            self.statistics.get_err_counter(self.peer4_in_err),
        )

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # route a packet into the wg interface
        #  this is dropped because the peer is still not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp6_err + 2, self.statistics.get_err_counter(self.kp6_error)
        )

        # send a data packet from the peer through the tunnel
        # this completes the handshake
        p = (
            IPv6(src="1::3:1", dst=self.pg0.remote_ip6, hlim=20)
            / UDP(sport=222, dport=223)
            / Raw()
        )
        d = peer_1.encrypt_transport(p)
        p = peer_1.mk_tunnel_header(self.pg1) / (
            Wireguard(message_type=4, reserved_zero=0)
            / WireguardTransport(
                receiver_index=peer_1.sender, counter=0, encrypted_encapsulated_packet=d
            )
        )
        rxs = self.send_and_expect(self.pg1, [p], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(rx[IPv6].hlim, 19)

        # send a packets that are routed into the tunnel
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        for rx in rxs:
            rx = IPv6(peer_1.decrypt_transport(rx))

            # check the original packet is present
            self.assertEqual(rx[IPv6].dst, p[IPv6].dst)
            self.assertEqual(rx[IPv6].hlim, p[IPv6].hlim - 1)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii + 1,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IPv6(src="1::3:1", dst=self.pg0.remote_ip6, hlim=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
            self.assertEqual(rx[IPv6].hlim, 19)

        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_peer_v4o6(self):
        """Test v4o6"""

        port = 12363

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip6, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # route a packet into the wg interface
        #  use the allowed-ip prefix
        #  this is dropped because the peer is not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp4_err + 1, self.statistics.get_err_counter(self.kp4_error)
        )

        # send a handsake from the peer with an invalid MAC
        p = peer_1.mk_handshake(self.pg1, True)
        p[WireguardInitiation].mac1 = b"foobar"
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])
        self.assertEqual(
            self.base_mac6_err + 1, self.statistics.get_err_counter(self.mac6_error)
        )

        # send a handsake from the peer but signed by the wrong key.
        p = peer_1.mk_handshake(
            self.pg1, True, X25519PrivateKey.generate().public_key()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg1, [p])
        self.assertEqual(
            self.base_peer6_in_err + 1,
            self.statistics.get_err_counter(self.peer6_in_err),
        )

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1, True)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0], True)

        # route a packet into the wg interface
        #  this is dropped because the peer is still not initiated
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        self.send_and_assert_no_replies_ignoring_init(self.pg0, [p])
        self.assertEqual(
            self.base_kp4_err + 2, self.statistics.get_err_counter(self.kp4_error)
        )

        # send a data packet from the peer through the tunnel
        # this completes the handshake
        p = (
            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
            / UDP(sport=222, dport=223)
            / Raw()
        )
        d = peer_1.encrypt_transport(p)
        p = peer_1.mk_tunnel_header(self.pg1, True) / (
            Wireguard(message_type=4, reserved_zero=0)
            / WireguardTransport(
                receiver_index=peer_1.sender, counter=0, encrypted_encapsulated_packet=d
            )
        )
        rxs = self.send_and_expect(self.pg1, [p], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        for rx in rxs:
            rx = IP(peer_1.decrypt_transport(rx, True))

            # check the original packet is present
            self.assertEqual(rx[IP].dst, p[IP].dst)
            self.assertEqual(rx[IP].ttl, p[IP].ttl - 1)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1, True)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii + 1,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_multi_peer(self):
        """multiple peer setup"""
        port = 12373

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg1 = VppWgInterface(self, self.pg2.local_ip4, port + 1).add_vpp_config()
        wg0.admin_up()
        wg1.admin_up()

        # Check peer counter
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 0)

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

        # Create many peers on sencond interface
        NUM_PEERS = 16
        self.pg2.generate_remote_hosts(NUM_PEERS)
        self.pg2.configure_ipv4_neighbors()
        self.pg1.generate_remote_hosts(NUM_PEERS)
        self.pg1.configure_ipv4_neighbors()

        peers_1 = []
        peers_2 = []
        routes_1 = []
        routes_2 = []
        for i in range(NUM_PEERS):
            peers_1.append(
                VppWgPeer(
                    self,
                    wg0,
                    self.pg1.remote_hosts[i].ip4,
                    port + 1 + i,
                    ["10.0.%d.4/32" % i],
                ).add_vpp_config()
            )
            routes_1.append(
                VppIpRoute(
                    self,
                    "10.0.%d.4" % i,
                    32,
                    [VppRoutePath(self.pg1.remote_hosts[i].ip4, wg0.sw_if_index)],
                ).add_vpp_config()
            )

            peers_2.append(
                VppWgPeer(
                    self,
                    wg1,
                    self.pg2.remote_hosts[i].ip4,
                    port + 100 + i,
                    ["10.100.%d.4/32" % i],
                ).add_vpp_config()
            )
            routes_2.append(
                VppIpRoute(
                    self,
                    "10.100.%d.4" % i,
                    32,
                    [VppRoutePath(self.pg2.remote_hosts[i].ip4, wg1.sw_if_index)],
                ).add_vpp_config()
            )

        self.assertEqual(len(self.vapi.wireguard_peers_dump()), NUM_PEERS * 2)

        self.logger.info(self.vapi.cli("show wireguard peer"))
        self.logger.info(self.vapi.cli("show wireguard interface"))
        self.logger.info(self.vapi.cli("show adj 37"))
        self.logger.info(self.vapi.cli("sh ip fib 172.16.3.17"))
        self.logger.info(self.vapi.cli("sh ip fib 10.11.3.0"))

        # remove routes
        for r in routes_1:
            r.remove_vpp_config()
        for r in routes_2:
            r.remove_vpp_config()

        # remove peers
        for p in peers_1:
            self.assertTrue(p.query_vpp_config())
            p.remove_vpp_config()
        for p in peers_2:
            self.assertTrue(p.query_vpp_config())
            p.remove_vpp_config()

        wg0.remove_vpp_config()
        wg1.remove_vpp_config()

    def test_wg_multi_interface(self):
        """Multi-tunnel on the same port"""
        port = 12500

        # Create many wireguard interfaces
        NUM_IFS = 4
        self.pg1.generate_remote_hosts(NUM_IFS)
        self.pg1.configure_ipv4_neighbors()
        self.pg0.generate_remote_hosts(NUM_IFS)
        self.pg0.configure_ipv4_neighbors()

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

        # Create interfaces with a peer on each
        peers = []
        routes = []
        wg_ifs = []
        for i in range(NUM_IFS):
            # Use the same port for each interface
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()
            wg_ifs.append(wg0)
            peers.append(
                VppWgPeer(
                    self,
                    wg0,
                    self.pg1.remote_hosts[i].ip4,
                    port + 1 + i,
                    ["10.0.%d.0/24" % i],
                ).add_vpp_config()
            )

            routes.append(
                VppIpRoute(
                    self,
                    "10.0.%d.0" % i,
                    24,
                    [VppRoutePath("10.0.%d.4" % i, wg0.sw_if_index)],
                ).add_vpp_config()
            )

        self.assertEqual(len(self.vapi.wireguard_peers_dump()), NUM_IFS)

        # skip the first automatic handshake
        self.pg1.get_capture(NUM_IFS, timeout=HANDSHAKE_JITTER)

        for i in range(NUM_IFS):
            # send a valid handsake init for which we expect a response
            p = peers[i].mk_handshake(self.pg1)
            rx = self.send_and_expect(self.pg1, [p], self.pg1)
            peers[i].consume_response(rx[0])

            # send a data packet from the peer through the tunnel
            # this completes the handshake
            p = (
                IP(src="10.0.%d.4" % i, dst=self.pg0.remote_hosts[i].ip4, ttl=20)
                / UDP(sport=222, dport=223)
                / Raw()
            )
            d = peers[i].encrypt_transport(p)
            p = peers[i].mk_tunnel_header(self.pg1) / (
                Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peers[i].sender,
                    counter=0,
                    encrypted_encapsulated_packet=d,
                )
            )
            rxs = self.send_and_expect(self.pg1, [p], self.pg0)
            for rx in rxs:
                self.assertEqual(rx[IP].dst, self.pg0.remote_hosts[i].ip4)
                self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        for i in range(NUM_IFS):
            p = (
                Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
                / IP(src=self.pg0.remote_hosts[i].ip4, dst="10.0.%d.4" % i)
                / UDP(sport=555, dport=556)
                / Raw(b"\x00" * 80)
            )

            rxs = self.send_and_expect(self.pg0, p * 64, self.pg1)

            for rx in rxs:
                rx = IP(peers[i].decrypt_transport(rx))

                # check the oringial packet is present
                self.assertEqual(rx[IP].dst, p[IP].dst)
                self.assertEqual(rx[IP].ttl, p[IP].ttl - 1)

        # send packets into the tunnel
        for i in range(NUM_IFS):
            p = [
                (
                    peers[i].mk_tunnel_header(self.pg1)
                    / Wireguard(message_type=4, reserved_zero=0)
                    / WireguardTransport(
                        receiver_index=peers[i].sender,
                        counter=ii + 1,
                        encrypted_encapsulated_packet=peers[i].encrypt_transport(
                            (
                                IP(
                                    src="10.0.%d.4" % i,
                                    dst=self.pg0.remote_hosts[i].ip4,
                                    ttl=20,
                                )
                                / UDP(sport=222, dport=223)
                                / Raw()
                            )
                        ),
                    )
                )
                for ii in range(64)
            ]

            rxs = self.send_and_expect(self.pg1, p, self.pg0)

            for rx in rxs:
                self.assertEqual(rx[IP].dst, self.pg0.remote_hosts[i].ip4)
                self.assertEqual(rx[IP].ttl, 19)

        for r in routes:
            r.remove_vpp_config()
        for p in peers:
            p.remove_vpp_config()
        for i in wg_ifs:
            i.remove_vpp_config()

    def test_wg_event(self):
        """Test events"""
        port = 12600
        ESTABLISHED_FLAG = (
            VppEnum.vl_api_wireguard_peer_flags_t.WIREGUARD_PEER_ESTABLISHED
        )
        DEAD_FLAG = VppEnum.vl_api_wireguard_peer_flags_t.WIREGUARD_PEER_STATUS_DEAD

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg1 = VppWgInterface(self, self.pg2.local_ip4, port + 1).add_vpp_config()
        wg0.admin_up()
        wg1.admin_up()

        # Check peer counter
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 0)

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

        # Create peers
        NUM_PEERS = 2
        self.pg2.generate_remote_hosts(NUM_PEERS)
        self.pg2.configure_ipv4_neighbors()
        self.pg1.generate_remote_hosts(NUM_PEERS)
        self.pg1.configure_ipv4_neighbors()

        peers_0 = []
        peers_1 = []
        routes_0 = []
        routes_1 = []
        for i in range(NUM_PEERS):
            peers_0.append(
                VppWgPeer(
                    self,
                    wg0,
                    self.pg1.remote_hosts[i].ip4,
                    port + 1 + i,
                    ["10.0.%d.4/32" % i],
                ).add_vpp_config()
            )
            routes_0.append(
                VppIpRoute(
                    self,
                    "10.0.%d.4" % i,
                    32,
                    [VppRoutePath(self.pg1.remote_hosts[i].ip4, wg0.sw_if_index)],
                ).add_vpp_config()
            )

            peers_1.append(
                VppWgPeer(
                    self,
                    wg1,
                    self.pg2.remote_hosts[i].ip4,
                    port + 100 + i,
                    ["10.100.%d.4/32" % i],
                ).add_vpp_config()
            )
            routes_1.append(
                VppIpRoute(
                    self,
                    "10.100.%d.4" % i,
                    32,
                    [VppRoutePath(self.pg2.remote_hosts[i].ip4, wg1.sw_if_index)],
                ).add_vpp_config()
            )

        self.assertEqual(len(self.vapi.wireguard_peers_dump()), NUM_PEERS * 2)

        # skip the first automatic handshake
        self.pg1.get_capture(NUM_PEERS, timeout=HANDSHAKE_JITTER)
        self.pg2.get_capture(NUM_PEERS, timeout=HANDSHAKE_JITTER)

        # Want events from the first perr of wg0
        # and from all wg1 peers
        peers_0[0].want_events()
        wg1.want_events()

        for i in range(NUM_PEERS):
            # wg0 peers: send a valid handsake init for which we expect a response
            p = peers_0[i].mk_handshake(self.pg1)
            rx = self.send_and_expect(self.pg1, [p], self.pg1)
            peers_0[i].consume_response(rx[0])

            # wg0 peers: send empty packet, it means successful connection (WIREGUARD_PEER_ESTABLISHED)
            keepalive = peers_0[i].encrypt_transport(0)
            p = peers_0[i].mk_tunnel_header(self.pg1) / (
                Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peers_0[i].sender,
                    counter=0,
                    encrypted_encapsulated_packet=keepalive,
                )
            )
            self.send_and_assert_no_replies(self.pg1, [p])

            # wg0 peers: wait for established flag
            if i == 0:
                peers_0[0].wait_event(ESTABLISHED_FLAG)

            # wg1 peers: send a valid handsake init for which we expect a response
            p = peers_1[i].mk_handshake(self.pg2)
            rx = self.send_and_expect(self.pg2, [p], self.pg2)
            peers_1[i].consume_response(rx[0])

            # wg1 peers: send empty packet, it means successful connection (WIREGUARD_PEER_ESTABLISHED)
            keepalive = peers_1[i].encrypt_transport(0)
            p = peers_1[i].mk_tunnel_header(self.pg2) / (
                Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peers_1[i].sender,
                    counter=0,
                    encrypted_encapsulated_packet=keepalive,
                )
            )
            self.send_and_assert_no_replies(self.pg2, [p])

        # wg1 peers: wait for established flag
        wg1.wait_events(ESTABLISHED_FLAG, [peers_1[0].index, peers_1[1].index])

        # remove routes
        for r in routes_0:
            r.remove_vpp_config()
        for r in routes_1:
            r.remove_vpp_config()

        # remove peers
        for i in range(NUM_PEERS):
            self.assertTrue(peers_0[i].query_vpp_config())
            peers_0[i].remove_vpp_config()
            if i == 0:
                peers_0[i].wait_event(0)
                peers_0[i].wait_event(DEAD_FLAG)
        for p in peers_1:
            self.assertTrue(p.query_vpp_config())
            p.remove_vpp_config()
            p.wait_event(0)
            p.wait_event(DEAD_FLAG)

        wg0.remove_vpp_config()
        wg1.remove_vpp_config()

    def test_wg_sending_handshake_when_admin_down(self):
        """Sending handshake when admin down"""
        port = 12323

        # create wg interface
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.config_ip4()

        # create a peer
        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

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

        # wait for the peer to send a handshake initiation
        # expect no handshakes
        for i in range(2):
            self.pg1.assert_nothing_captured(remark="handshake packet(s) sent")

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

        # administratively enable the wg interface
        # expect the peer to send a handshake initiation
        wg0.admin_up()
        rxs = self.pg1.get_capture(1, timeout=2)
        peer_1.consume_init(rxs[0], self.pg1)

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

        # administratively disable the wg interface
        # expect no handshakes
        wg0.admin_down()
        for i in range(6):
            self.pg1.assert_nothing_captured(remark="handshake packet(s) sent")

        # remove configs
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_sending_data_when_admin_down(self):
        """Sending data when admin down"""
        port = 12323

        # create wg interface
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        # create a peer
        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # create a route to rewrite traffic into the wg interface
        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # wait for the peer to send a handshake initiation
        rxs = self.pg1.get_capture(1, timeout=2)

        # prepare and send a handshake response
        # expect a keepalive message
        resp = peer_1.consume_init(rxs[0], self.pg1)
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        # verify the keepalive message
        b = peer_1.decrypt_transport(rxs[0])
        self.assertEqual(0, len(b))

        # prepare and send a packet that will be rewritten into the wg interface
        # expect a data packet sent
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        rxs = self.send_and_expect(self.pg0, [p], self.pg1)

        # verify the data packet
        peer_1.validate_encapped(rxs, p)

        # administratively disable the wg interface
        wg0.admin_down()

        # send a packet that will be rewritten into the wg interface
        # expect no data packets sent
        self.send_and_assert_no_replies(self.pg0, [p])

        # administratively enable the wg interface
        # expect the peer to send a handshake initiation
        wg0.admin_up()
        peer_1.noise_reset()
        rxs = self.pg1.get_capture(1, timeout=2)
        resp = peer_1.consume_init(rxs[0], self.pg1)

        # send a packet that will be rewritten into the wg interface
        # expect no data packets sent because the peer is not initiated
        self.send_and_assert_no_replies(self.pg0, [p])
        self.assertEqual(
            self.base_kp4_err + 1, self.statistics.get_err_counter(self.kp4_error)
        )

        # send a handshake response and expect a keepalive message
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        # verify the keepalive message
        b = peer_1.decrypt_transport(rxs[0])
        self.assertEqual(0, len(b))

        # send a packet that will be rewritten into the wg interface
        # expect a data packet sent
        rxs = self.send_and_expect(self.pg0, [p], self.pg1)

        # verify the data packet
        peer_1.validate_encapped(rxs, p)

        # remove configs
        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def _test_wg_large_packet_tmpl(self, is_async, is_ip6):
        self.vapi.wg_set_async_mode(is_async)
        port = 12323

        # create wg interface
        if is_ip6:
            wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip6()
        else:
            wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
            wg0.admin_up()
            wg0.config_ip4()

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

        # create a peer
        if is_ip6:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip6, port + 1, ["1::3:0/112"]
            ).add_vpp_config()
        else:
            peer_1 = VppWgPeer(
                self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
            ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # create a route to rewrite traffic into the wg interface
        if is_ip6:
            r1 = VppIpRoute(
                self, "1::3:0", 112, [VppRoutePath("1::3:1", wg0.sw_if_index)]
            ).add_vpp_config()
        else:
            r1 = VppIpRoute(
                self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
            ).add_vpp_config()

        # wait for the peer to send a handshake initiation
        rxs = self.pg1.get_capture(1, timeout=2)

        # prepare and send a handshake response
        # expect a keepalive message
        resp = peer_1.consume_init(rxs[0], self.pg1, is_ip6=is_ip6)
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        # verify the keepalive message
        b = peer_1.decrypt_transport(rxs[0], is_ip6=is_ip6)
        self.assertEqual(0, len(b))

        # prepare and send data packets
        # expect to receive them decrypted
        if is_ip6:
            ip_header = IPv6(src="1::3:1", dst=self.pg0.remote_ip6, hlim=20)
        else:
            ip_header = IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
        packet_len_opts = (
            2500,  # two buffers
            1500,  # one buffer
            4500,  # three buffers
            1910 if is_ip6 else 1950,  # auth tag is not contiguous
        )
        txs = []
        for l in packet_len_opts:
            txs.append(
                peer_1.mk_tunnel_header(self.pg1, is_ip6=is_ip6)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=len(txs),
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        ip_header / UDP(sport=222, dport=223) / Raw(b"\xfe" * l)
                    ),
                )
            )
        rxs = self.send_and_expect(self.pg1, txs, self.pg0)

        # verify decrypted packets
        for i, l in enumerate(packet_len_opts):
            if is_ip6:
                self.assertEqual(rxs[i][IPv6].dst, self.pg0.remote_ip6)
                self.assertEqual(rxs[i][IPv6].hlim, ip_header.hlim - 1)
            else:
                self.assertEqual(rxs[i][IP].dst, self.pg0.remote_ip4)
                self.assertEqual(rxs[i][IP].ttl, ip_header.ttl - 1)
            self.assertEqual(len(rxs[i][Raw]), l)
            self.assertEqual(bytes(rxs[i][Raw]), b"\xfe" * l)

        # prepare and send packets that will be rewritten into the wg interface
        # expect data packets sent
        if is_ip6:
            ip_header = IPv6(src=self.pg0.remote_ip6, dst="1::3:2")
        else:
            ip_header = IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
        packet_len_opts = (
            2500,  # two buffers
            1500,  # one buffer
            4500,  # three buffers
            1980 if is_ip6 else 2000,  # no free space to write auth tag
        )
        txs = []
        for l in packet_len_opts:
            txs.append(
                Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
                / ip_header
                / UDP(sport=555, dport=556)
                / Raw(b"\xfe" * l)
            )
        rxs = self.send_and_expect(self.pg0, txs, self.pg1)

        # verify the data packets
        rxs_decrypted = peer_1.validate_encapped(
            rxs, ip_header, is_tunnel_ip6=is_ip6, is_transport_ip6=is_ip6
        )

        for i, l in enumerate(packet_len_opts):
            self.assertEqual(len(rxs_decrypted[i][Raw]), l)
            self.assertEqual(bytes(rxs_decrypted[i][Raw]), b"\xfe" * l)

        # remove configs
        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    def test_wg_large_packet_v4_sync(self):
        """Large packet (v4, sync)"""
        self._test_wg_large_packet_tmpl(is_async=False, is_ip6=False)

    def test_wg_large_packet_v6_sync(self):
        """Large packet (v6, sync)"""
        self._test_wg_large_packet_tmpl(is_async=False, is_ip6=True)

    def test_wg_large_packet_v4_async(self):
        """Large packet (v4, async)"""
        self._test_wg_large_packet_tmpl(is_async=True, is_ip6=False)

    def test_wg_large_packet_v6_async(self):
        """Large packet (v6, async)"""
        self._test_wg_large_packet_tmpl(is_async=True, is_ip6=True)

    def test_wg_lack_of_buf_headroom(self):
        """Lack of buffer's headroom (v6 vxlan over v6 wg)"""
        port = 12323

        # create wg interface
        wg0 = VppWgInterface(self, self.pg1.local_ip6, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip6()

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

        # create a peer
        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip6, port + 1, ["::/0"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # create a route to enable communication between wg interface addresses
        r1 = VppIpRoute(
            self, wg0.remote_ip6, 128, [VppRoutePath("0.0.0.0", wg0.sw_if_index)]
        ).add_vpp_config()

        # wait for the peer to send a handshake initiation
        rxs = self.pg1.get_capture(1, timeout=2)

        # prepare and send a handshake response
        # expect a keepalive message
        resp = peer_1.consume_init(rxs[0], self.pg1, is_ip6=True)
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        # verify the keepalive message
        b = peer_1.decrypt_transport(rxs[0], is_ip6=True)
        self.assertEqual(0, len(b))

        # create vxlan interface over the wg interface
        vxlan0 = VppVxlanTunnel(self, src=wg0.local_ip6, dst=wg0.remote_ip6, vni=1111)
        vxlan0.add_vpp_config()

        # create bridge domain
        bd1 = VppBridgeDomain(self, bd_id=1)
        bd1.add_vpp_config()

        # add the vxlan interface and pg0 to the bridge domain
        bd1_ports = (
            VppBridgeDomainPort(self, bd1, vxlan0).add_vpp_config(),
            VppBridgeDomainPort(self, bd1, self.pg0).add_vpp_config(),
        )

        # prepare and send packets that will be rewritten into the vxlan interface
        # expect they to be rewritten into the wg interface then and data packets sent
        tx = (
            Ether(dst="00:00:00:00:00:01", src="00:00:00:00:00:02")
            / IPv6(src="::1", dst="::2", hlim=20)
            / UDP(sport=1111, dport=1112)
            / Raw(b"\xfe" * 1900)
        )
        rxs = self.send_and_expect(self.pg0, [tx] * 5, self.pg1)

        # verify the data packet
        for rx in rxs:
            rx_decrypted = IPv6(peer_1.decrypt_transport(rx, is_ip6=True))

            self.assertEqual(rx_decrypted[VXLAN].vni, vxlan0.vni)
            inner = rx_decrypted[VXLAN].payload

            # check the original packet is present
            self.assertEqual(inner[IPv6].dst, tx[IPv6].dst)
            self.assertEqual(inner[IPv6].hlim, tx[IPv6].hlim)
            self.assertEqual(len(inner[Raw]), len(tx[Raw]))
            self.assertEqual(bytes(inner[Raw]), bytes(tx[Raw]))

        # remove configs
        for bdp in bd1_ports:
            bdp.remove_vpp_config()
        bd1.remove_vpp_config()
        vxlan0.remove_vpp_config()
        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()


@tag_fixme_vpp_debug
class WireguardHandoffTests(TestWg):
    """Wireguard Tests in multi worker setup"""

    vpp_worker_count = 2

    def test_wg_peer_init(self):
        """Handoff"""

        port = 12383

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.2.0/24", "10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # skip the first automatic handshake
        self.pg1.get_capture(1, timeout=HANDSHAKE_JITTER)

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # send a data packet from the peer through the tunnel
        # this completes the handshake and pins the peer to worker 0
        p = (
            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
            / UDP(sport=222, dport=223)
            / Raw()
        )
        d = peer_1.encrypt_transport(p)
        p = peer_1.mk_tunnel_header(self.pg1) / (
            Wireguard(message_type=4, reserved_zero=0)
            / WireguardTransport(
                receiver_index=peer_1.sender, counter=0, encrypted_encapsulated_packet=d
            )
        )
        rxs = self.send_and_expect(self.pg1, [p], self.pg0, worker=0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        # and pins the peer tp worker 1
        pe = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw(b"\x00" * 80)
        )
        rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=1)
        peer_1.validate_encapped(rxs, pe)

        # send packets into the tunnel, from the other worker
        p = [
            (
                peer_1.mk_tunnel_header(self.pg1)
                / Wireguard(message_type=4, reserved_zero=0)
                / WireguardTransport(
                    receiver_index=peer_1.sender,
                    counter=ii + 1,
                    encrypted_encapsulated_packet=peer_1.encrypt_transport(
                        (
                            IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20)
                            / UDP(sport=222, dport=223)
                            / Raw()
                        )
                    ),
                )
            )
            for ii in range(255)
        ]

        rxs = self.send_and_expect(self.pg1, p, self.pg0, worker=1)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        # from worker 0
        rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=0)

        peer_1.validate_encapped(rxs, pe)

        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()

    @unittest.skip("test disabled")
    def test_wg_multi_interface(self):
        """Multi-tunnel on the same port"""


class TestWgFIB(VppTestCase):
    """Wireguard FIB Test Case"""

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

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

    def setUp(self):
        super(TestWgFIB, self).setUp()

        self.create_pg_interfaces(range(2))

        for i in self.pg_interfaces:
            i.admin_up()
            i.config_ip4()

    def tearDown(self):
        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.admin_down()
        super(TestWgFIB, self).tearDown()

    def test_wg_fib_tracking(self):
        """FIB tracking"""
        port = 12323

        # create wg interface
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

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

        # create a peer
        peer_1 = VppWgPeer(
            self, wg0, self.pg1.remote_ip4, port + 1, ["10.11.3.0/24"]
        ).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # create a route to rewrite traffic into the wg interface
        r1 = VppIpRoute(
            self, "10.11.3.0", 24, [VppRoutePath("10.11.3.1", wg0.sw_if_index)]
        ).add_vpp_config()

        # resolve ARP and expect the adjacency to update
        self.pg1.resolve_arp()

        # wait for the peer to send a handshake initiation
        rxs = self.pg1.get_capture(2, timeout=6)

        # prepare and send a handshake response
        # expect a keepalive message
        resp = peer_1.consume_init(rxs[1], self.pg1)
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        # verify the keepalive message
        b = peer_1.decrypt_transport(rxs[0])
        self.assertEqual(0, len(b))

        # prepare and send a packet that will be rewritten into the wg interface
        # expect a data packet sent
        p = (
            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
            / IP(src=self.pg0.remote_ip4, dst="10.11.3.2")
            / UDP(sport=555, dport=556)
            / Raw()
        )
        rxs = self.send_and_expect(self.pg0, [p], self.pg1)

        # verify the data packet
        peer_1.validate_encapped(rxs, p)

        # remove configs
        r1.remove_vpp_config()
        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()
