import unittest
import socket
import struct

from scapy.layers.inet import IP, ICMP, TCP, UDP
from scapy.layers.ipsec import SecurityAssociation, ESP
from scapy.layers.l2 import Ether
from scapy.packet import raw, Raw
from scapy.layers.inet6 import (
    IPv6,
    ICMPv6EchoRequest,
    IPv6ExtHdrHopByHop,
    IPv6ExtHdrFragment,
    IPv6ExtHdrDestOpt,
)


from framework import VppTestCase
from asfframework import VppTestRunner
from util import ppp, reassemble4, fragment_rfc791, fragment_rfc8200
from vpp_papi import VppEnum

from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSpdItfBinding
from ipaddress import ip_address
from re import search
from os import popen
from config import config


class IPsecIPv4Params:
    addr_type = socket.AF_INET
    addr_any = "0.0.0.0"
    addr_bcast = "255.255.255.255"
    addr_len = 32
    is_ipv6 = 0

    def __init__(self):
        self.remote_tun_if_host = "1.1.1.1"
        self.remote_tun_if_host6 = "1111::1"

        self.scapy_tun_sa_id = 100
        self.scapy_tun_spi = 1000
        self.vpp_tun_sa_id = 200
        self.vpp_tun_spi = 2000

        self.scapy_tra_sa_id = 300
        self.scapy_tra_spi = 3000
        self.vpp_tra_sa_id = 400
        self.vpp_tra_spi = 4000

        self.outer_hop_limit = 64
        self.inner_hop_limit = 255
        self.outer_flow_label = 0
        self.inner_flow_label = 0x12345

        self.anti_replay_window_size = 64

        self.auth_algo_vpp_id = (
            VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96
        )
        self.auth_algo = "HMAC-SHA1-96"  # scapy name
        self.auth_key = b"C91KUR9GYMm5GfkEvNjX"

        self.crypt_algo_vpp_id = (
            VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128
        )
        self.crypt_algo = "AES-CBC"  # scapy name
        self.crypt_key = b"JPjyOWBeVEQiMe7h"
        self.salt = 0
        self.flags = 0
        self.nat_header = None
        self.tun_flags = (
            VppEnum.vl_api_tunnel_encap_decap_flags_t.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
        )
        self.dscp = 0
        self.async_mode = False


class IPsecIPv6Params:
    addr_type = socket.AF_INET6
    addr_any = "0::0"
    addr_bcast = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
    addr_len = 128
    is_ipv6 = 1

    def __init__(self):
        self.remote_tun_if_host = "1111:1111:1111:1111:1111:1111:1111:1111"
        self.remote_tun_if_host4 = "1.1.1.1"

        self.scapy_tun_sa_id = 500
        self.scapy_tun_spi = 3001
        self.vpp_tun_sa_id = 600
        self.vpp_tun_spi = 3000

        self.scapy_tra_sa_id = 700
        self.scapy_tra_spi = 4001
        self.vpp_tra_sa_id = 800
        self.vpp_tra_spi = 4000

        self.outer_hop_limit = 64
        self.inner_hop_limit = 255
        self.outer_flow_label = 0
        self.inner_flow_label = 0x12345

        self.anti_replay_window_size = 64

        self.auth_algo_vpp_id = (
            VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96
        )
        self.auth_algo = "HMAC-SHA1-96"  # scapy name
        self.auth_key = b"C91KUR9GYMm5GfkEvNjX"

        self.crypt_algo_vpp_id = (
            VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128
        )
        self.crypt_algo = "AES-CBC"  # scapy name
        self.crypt_key = b"JPjyOWBeVEQiMe7h"
        self.salt = 0
        self.flags = 0
        self.nat_header = None
        self.tun_flags = (
            VppEnum.vl_api_tunnel_encap_decap_flags_t.TUNNEL_API_ENCAP_DECAP_FLAG_NONE
        )
        self.dscp = 0
        self.async_mode = False


def mk_scapy_crypt_key(p):
    if p.crypt_algo in ("AES-GCM", "AES-CTR", "AES-NULL-GMAC"):
        return p.crypt_key + struct.pack("!I", p.salt)
    else:
        return p.crypt_key


def config_tun_params(p, encryption_type, tun_if):
    ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
    esn_en = bool(
        p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_USE_ESN)
    )
    p.tun_dst = tun_if.remote_addr[p.addr_type]
    p.tun_src = tun_if.local_addr[p.addr_type]
    crypt_key = mk_scapy_crypt_key(p)
    p.scapy_tun_sa = SecurityAssociation(
        encryption_type,
        spi=p.scapy_tun_spi,
        crypt_algo=p.crypt_algo,
        crypt_key=crypt_key,
        auth_algo=p.auth_algo,
        auth_key=p.auth_key,
        tunnel_header=ip_class_by_addr_type[p.addr_type](src=p.tun_dst, dst=p.tun_src),
        nat_t_header=p.nat_header,
        esn_en=esn_en,
    )
    p.vpp_tun_sa = SecurityAssociation(
        encryption_type,
        spi=p.vpp_tun_spi,
        crypt_algo=p.crypt_algo,
        crypt_key=crypt_key,
        auth_algo=p.auth_algo,
        auth_key=p.auth_key,
        tunnel_header=ip_class_by_addr_type[p.addr_type](dst=p.tun_dst, src=p.tun_src),
        nat_t_header=p.nat_header,
        esn_en=esn_en,
    )


def config_tra_params(p, encryption_type):
    esn_en = bool(
        p.flags & (VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_USE_ESN)
    )
    crypt_key = mk_scapy_crypt_key(p)
    p.scapy_tra_sa = SecurityAssociation(
        encryption_type,
        spi=p.scapy_tra_spi,
        crypt_algo=p.crypt_algo,
        crypt_key=crypt_key,
        auth_algo=p.auth_algo,
        auth_key=p.auth_key,
        nat_t_header=p.nat_header,
        esn_en=esn_en,
    )
    p.vpp_tra_sa = SecurityAssociation(
        encryption_type,
        spi=p.vpp_tra_spi,
        crypt_algo=p.crypt_algo,
        crypt_key=crypt_key,
        auth_algo=p.auth_algo,
        auth_key=p.auth_key,
        nat_t_header=p.nat_header,
        esn_en=esn_en,
    )


class TemplateIpsec(VppTestCase):
    """
    TRANSPORT MODE::

         ------   encrypt   ---
        |tra_if| <-------> |VPP|
         ------   decrypt   ---

    TUNNEL MODE::

         ------   encrypt   ---   plain   ---
        |tun_if| <-------  |VPP| <------ |pg1|
         ------             ---           ---

         ------   decrypt   ---   plain   ---
        |tun_if| ------->  |VPP| ------> |pg1|
         ------             ---           ---
    """

    tun_spd_id = 1
    tra_spd_id = 2

    def ipsec_select_backend(self):
        """empty method to be overloaded when necessary"""
        pass

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

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

    def setup_params(self):
        if not hasattr(self, "ipv4_params"):
            self.ipv4_params = IPsecIPv4Params()
        if not hasattr(self, "ipv6_params"):
            self.ipv6_params = IPsecIPv6Params()
        self.params = {
            self.ipv4_params.addr_type: self.ipv4_params,
            self.ipv6_params.addr_type: self.ipv6_params,
        }

    def config_interfaces(self):
        self.create_pg_interfaces(range(3))
        self.interfaces = list(self.pg_interfaces)
        for i in self.interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()
            i.config_ip6()
            i.resolve_ndp()

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

        self.setup_params()

        self.vpp_esp_protocol = VppEnum.vl_api_ipsec_proto_t.IPSEC_API_PROTO_ESP
        self.vpp_ah_protocol = VppEnum.vl_api_ipsec_proto_t.IPSEC_API_PROTO_AH

        self.config_interfaces()

        self.ipsec_select_backend()

    def unconfig_interfaces(self):
        for i in self.interfaces:
            i.admin_down()
            i.unconfig_ip4()
            i.unconfig_ip6()

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

        self.unconfig_interfaces()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show hardware"))

    def gen_encrypt_pkts(self, p, sa, sw_intf, src, dst, count=1, payload_size=54):
        return [
            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
            / sa.encrypt(IP(src=src, dst=dst) / ICMP() / Raw(b"X" * payload_size))
            for i in range(count)
        ]

    def gen_encrypt_pkts6(self, p, sa, sw_intf, src, dst, count=1, payload_size=54):
        return [
            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
            / sa.encrypt(
                IPv6(src=src, dst=dst, hlim=p.inner_hop_limit, fl=p.inner_flow_label)
                / ICMPv6EchoRequest(id=0, seq=1, data="X" * payload_size)
            )
            for i in range(count)
        ]

    def gen_pkts(self, sw_intf, src, dst, count=1, payload_size=54):
        return [
            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
            / IP(src=src, dst=dst)
            / ICMP()
            / Raw(b"X" * payload_size)
            for i in range(count)
        ]

    def gen_pkts6(self, p, sw_intf, src, dst, count=1, payload_size=54):
        return [
            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
            / IPv6(src=src, dst=dst, hlim=p.inner_hop_limit, fl=p.inner_flow_label)
            / ICMPv6EchoRequest(id=0, seq=1, data="X" * payload_size)
            for i in range(count)
        ]


class IpsecTcp(object):
    def verify_tcp_checksum(self):
        # start http cli server listener on http://0.0.0.0:80
        self.vapi.cli("http cli server")
        p = self.params[socket.AF_INET]
        send = Ether(
            src=self.tun_if.remote_mac, dst=self.tun_if.local_mac
        ) / p.scapy_tun_sa.encrypt(
            IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4)
            / TCP(flags="S", dport=80)
        )
        self.logger.debug(ppp("Sending packet:", send))
        recv = self.send_and_expect(self.tun_if, [send], self.tun_if)
        recv = recv[0]
        decrypted = p.vpp_tun_sa.decrypt(recv[IP])
        self.assert_packet_checksums_valid(decrypted)


@unittest.skipIf(
    "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin"
)
class IpsecTcpTests(IpsecTcp):
    def test_tcp_checksum(self):
        """verify checksum correctness for vpp generated packets"""
        self.verify_tcp_checksum()


class IpsecTra4(object):
    """verify methods for Transport v4"""

    def get_replay_counts(self, p):
        replay_node_name = "/err/%s/replay" % self.tra4_decrypt_node_name[0]
        count = self.statistics.get_err_counter(replay_node_name)

        if p.async_mode:
            replay_post_node_name = (
                "/err/%s/replay" % self.tra4_decrypt_node_name[p.async_mode]
            )
            count += self.statistics.get_err_counter(replay_post_node_name)

        return count

    def get_hash_failed_counts(self, p):
        if ESP == self.encryption_type and p.crypt_algo in ("AES-GCM", "AES-NULL-GMAC"):
            hash_failed_node_name = (
                "/err/%s/decryption_failed" % self.tra4_decrypt_node_name[p.async_mode]
            )
        else:
            hash_failed_node_name = (
                "/err/%s/integ_error" % self.tra4_decrypt_node_name[p.async_mode]
            )
        count = self.statistics.get_err_counter(hash_failed_node_name)

        if p.async_mode:
            count += self.statistics.get_err_counter("/err/crypto-dispatch/bad-hmac")

        return count

    def verify_hi_seq_num(self):
        p = self.params[socket.AF_INET]
        saf = VppEnum.vl_api_ipsec_sad_flags_t
        esn_on = p.vpp_tra_sa.esn_en
        ar_on = p.flags & saf.IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY

        seq_cycle_node_name = "/err/%s/seq_cycled" % self.tra4_encrypt_node_name
        replay_count = self.get_replay_counts(p)
        hash_failed_count = self.get_hash_failed_counts(p)
        seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)

        # a few packets so we get the rx seq number above the window size and
        # thus can simulate a wrap with an out of window packet
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(63, 80)
        ]
        recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # these 4 packets will all choose seq-num 0 to decrpyt since none
        # are out of window when first checked. however, once #200 has
        # decrypted it will move the window to 200 and has #81 is out of
        # window. this packet should be dropped.
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=200,
                )
            ),
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=81,
                )
            ),
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=201,
                )
            ),
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=202,
                )
            ),
        ]

        # if anti-replay is off then we won't drop #81
        n_rx = 3 if ar_on else 4
        self.send_and_expect(self.tra_if, pkts, self.tra_if, n_rx=n_rx)
        # this packet is one before the wrap
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=203,
                )
            )
        ]
        recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # a replayed packet, then an out of window, then a legit
        # tests that a early failure on the batch doesn't affect subsequent packets.
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=203,
                )
            ),
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=81,
                )
            ),
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=204,
                )
            ),
        ]
        n_rx = 1 if ar_on else 3
        recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if, n_rx=n_rx)

        # move the window over half way to a wrap
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=0x80000001,
                )
            )
        ]
        recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # anti-replay will drop old packets, no anti-replay will not
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=0x44000001,
                )
            )
        ]

        if ar_on:
            self.send_and_assert_no_replies(self.tra_if, pkts)
        else:
            recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)

        if esn_on:
            #
            # validate wrapping the ESN
            #

            # wrap scapy's TX SA SN
            p.scapy_tra_sa.seq_num = 0x100000005

            # send a packet that wraps the window for both AR and no AR
            pkts = [
                (
                    Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                    / p.scapy_tra_sa.encrypt(
                        IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                        / ICMP(),
                        seq_num=0x100000005,
                    )
                )
            ]

            rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)
            for rx in rxs:
                decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            # move the window forward to half way to the next wrap
            pkts = [
                (
                    Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                    / p.scapy_tra_sa.encrypt(
                        IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                        / ICMP(),
                        seq_num=0x180000005,
                    )
                )
            ]

            rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)

            # a packet less than 2^30 from the current position is:
            #  - AR: out of window and dropped
            #  - non-AR: accepted
            pkts = [
                (
                    Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                    / p.scapy_tra_sa.encrypt(
                        IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                        / ICMP(),
                        seq_num=0x170000005,
                    )
                )
            ]

            if ar_on:
                self.send_and_assert_no_replies(self.tra_if, pkts)
            else:
                self.send_and_expect(self.tra_if, pkts, self.tra_if)

            # a packet more than 2^30 from the current position is:
            #  - AR: out of window and dropped
            #  - non-AR: considered a wrap, but since it's not a wrap
            #    it won't decrpyt and so will be dropped
            pkts = [
                (
                    Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                    / p.scapy_tra_sa.encrypt(
                        IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                        / ICMP(),
                        seq_num=0x130000005,
                    )
                )
            ]

            self.send_and_assert_no_replies(self.tra_if, pkts)

            # a packet less than 2^30 from the current position and is a
            # wrap; (the seq is currently at 0x180000005).
            #  - AR: out of window so considered a wrap, so accepted
            #  - non-AR: not considered a wrap, so won't decrypt
            p.scapy_tra_sa.seq_num = 0x260000005
            pkts = [
                (
                    Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                    / p.scapy_tra_sa.encrypt(
                        IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                        / ICMP(),
                        seq_num=0x260000005,
                    )
                )
            ]
            if ar_on:
                self.send_and_expect(self.tra_if, pkts, self.tra_if)
            else:
                self.send_and_assert_no_replies(self.tra_if, pkts)

            #
            # window positions are different now for AR/non-AR
            #  move non-AR forward
            #
            if not ar_on:
                # a packet more than 2^30 from the current position and is a
                # wrap; (the seq is currently at 0x180000005).
                #  - AR: accepted
                #  - non-AR: not considered a wrap, so won't decrypt

                pkts = [
                    (
                        Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                        / p.scapy_tra_sa.encrypt(
                            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                            / ICMP(),
                            seq_num=0x200000005,
                        )
                    ),
                    (
                        Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                        / p.scapy_tra_sa.encrypt(
                            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                            / ICMP(),
                            seq_num=0x200000006,
                        )
                    ),
                ]
                self.send_and_expect(self.tra_if, pkts, self.tra_if)

                pkts = [
                    (
                        Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                        / p.scapy_tra_sa.encrypt(
                            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4)
                            / ICMP(),
                            seq_num=0x260000005,
                        )
                    )
                ]
                self.send_and_expect(self.tra_if, pkts, self.tra_if)

    def verify_tra_anti_replay(self):
        p = self.params[socket.AF_INET]
        esn_en = p.vpp_tra_sa.esn_en
        anti_replay_window_size = p.anti_replay_window_size

        seq_cycle_node_name = "/err/%s/seq_cycled" % self.tra4_encrypt_node_name
        replay_count = self.get_replay_counts(p)
        initial_sa_node_replay_diff = replay_count - p.tra_sa_in.get_err("replay")
        hash_failed_count = self.get_hash_failed_counts(p)
        seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)
        initial_sa_node_cycled_diff = seq_cycle_count - p.tra_sa_in.get_err(
            "seq_cycled"
        )
        hash_err = "integ_error"

        if ESP == self.encryption_type:
            undersize_node_name = "/err/%s/runt" % self.tra4_decrypt_node_name[0]
            undersize_count = self.statistics.get_err_counter(undersize_node_name)
            initial_sa_node_undersize_diff = undersize_count - p.tra_sa_in.get_err(
                "runt"
            )
            # For AES-GCM an error in the hash is reported as a decryption failure
            if p.crypt_algo in ("AES-GCM", "AES-NULL-GMAC"):
                hash_err = "decryption_failed"
        # In async mode, we don't report errors in the hash.
        if p.async_mode:
            hash_err = ""
        else:
            initial_sa_node_hash_diff = hash_failed_count - p.tra_sa_in.get_err(
                hash_err
            )

        #
        # send packets with seq numbers 1->34
        # this means the window size is still in Case B (see RFC4303
        # Appendix A)
        #
        # for reasons i haven't investigated Scapy won't create a packet with
        # seq_num=0
        #
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(1, 34)
        ]
        recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # replayed packets are dropped
        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
        replay_count += len(pkts)
        self.assertEqual(self.get_replay_counts(p), replay_count)
        err = p.tra_sa_in.get_err("replay") + initial_sa_node_replay_diff
        self.assertEqual(err, replay_count)

        #
        # now send a batch of packets all with the same sequence number
        # the first packet in the batch is legitimate, the rest bogus
        #
        self.vapi.cli("clear error")
        self.vapi.cli("clear node counters")
        pkts = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / p.scapy_tra_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=35,
        )
        recv_pkts = self.send_and_expect(self.tra_if, pkts * 8, self.tra_if, n_rx=1)
        replay_count += 7
        self.assertEqual(self.get_replay_counts(p), replay_count)
        err = p.tra_sa_in.get_err("replay") + initial_sa_node_replay_diff
        self.assertEqual(err, replay_count)

        #
        # now move the window over to anti_replay_window_size + 100 and into Case A
        #
        self.vapi.cli("clear error")
        pkt = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / p.scapy_tra_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=anti_replay_window_size + 100,
        )
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        self.logger.info(self.vapi.ppcli("show ipsec sa 1"))

        # replayed packets are dropped
        self.send_and_assert_no_replies(self.tra_if, pkt * 3, timeout=0.2)
        replay_count += 3
        self.assertEqual(self.get_replay_counts(p), replay_count)
        err = p.tra_sa_in.get_err("replay") + initial_sa_node_replay_diff
        self.assertEqual(err, replay_count)

        # the window size is anti_replay_window_size packets
        # in window are still accepted
        pkt = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / p.scapy_tra_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=200,
        )

        # a packet that does not decrypt does not move the window forward
        bogus_sa = SecurityAssociation(
            self.encryption_type,
            p.scapy_tra_spi,
            crypt_algo=p.crypt_algo,
            crypt_key=mk_scapy_crypt_key(p)[::-1],
            auth_algo=p.auth_algo,
            auth_key=p.auth_key[::-1],
        )
        pkt = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / bogus_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=anti_replay_window_size + 200,
        )
        self.send_and_assert_no_replies(self.tra_if, pkt * 17, timeout=0.2)

        hash_failed_count += 17
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)
        if hash_err != "":
            err = p.tra_sa_in.get_err(hash_err) + initial_sa_node_hash_diff
            self.assertEqual(err, hash_failed_count)

        # a malformed 'runt' packet
        #  created by a mis-constructed SA
        if ESP == self.encryption_type and p.crypt_algo != "NULL":
            bogus_sa = SecurityAssociation(self.encryption_type, p.scapy_tra_spi)
            pkt = Ether(
                src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
            ) / bogus_sa.encrypt(
                IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                seq_num=anti_replay_window_size + 200,
            )
            self.send_and_assert_no_replies(self.tra_if, pkt * 17, timeout=0.2)

            undersize_count += 17
            self.assert_error_counter_equal(undersize_node_name, undersize_count)
            err = p.tra_sa_in.get_err("runt") + initial_sa_node_undersize_diff
            self.assertEqual(err, undersize_count)

        # which we can determine since this packet is still in the window
        pkt = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / p.scapy_tra_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=234,
        )
        self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        #
        # out of window are dropped
        #  this is Case B. So VPP will consider this to be a high seq num wrap
        #  and so the decrypt attempt will fail
        #
        pkt = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / p.scapy_tra_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=17,
        )
        self.send_and_assert_no_replies(self.tra_if, pkt * 17, timeout=0.2)

        if esn_en:
            # an out of window error with ESN looks like a high sequence
            # wrap. but since it isn't then the verify will fail.
            hash_failed_count += 17
            self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)
            if hash_err != "":
                err = p.tra_sa_in.get_err(hash_err) + initial_sa_node_hash_diff
                self.assertEqual(err, hash_failed_count)

        else:
            replay_count += 17
            self.assertEqual(self.get_replay_counts(p), replay_count)
            err = p.tra_sa_in.get_err("replay") + initial_sa_node_replay_diff
            self.assertEqual(err, replay_count)

        # valid packet moves the window over to anti_replay_window_size + 258
        pkt = Ether(
            src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
        ) / p.scapy_tra_sa.encrypt(
            IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
            seq_num=anti_replay_window_size + 258,
        )
        rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
        decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

        #
        # move VPP's SA TX seq-num to just before the seq-number wrap.
        # then fire in a packet that VPP should drop on TX because it
        # causes the TX seq number to wrap; unless we're using extened sequence
        # numbers.
        #
        self.vapi.cli("test ipsec sa %d seq 0xffffffff" % p.vpp_tra_sa_id)
        self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
        self.logger.info(self.vapi.ppcli("show ipsec sa 1"))

        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(259, 280)
        ]

        if esn_en:
            rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)

            #
            # in order for scapy to decrypt its SA's high order number needs
            # to wrap
            #
            p.vpp_tra_sa.seq_num = 0x100000000
            for rx in rxs:
                decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            #
            # wrap scapy's TX high sequence number. VPP is in case B, so it
            # will consider this a high seq wrap also.
            # The low seq num we set it to will place VPP's RX window in Case A
            #
            p.scapy_tra_sa.seq_num = 0x100000005
            pkt = Ether(
                src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
            ) / p.scapy_tra_sa.encrypt(
                IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                seq_num=0x100000005,
            )
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            #
            # A packet that has seq num between (2^32-anti_replay_window_size)+4 and 5 is within
            # the window
            #
            p.scapy_tra_sa.seq_num = 0xFFFFFFFD
            pkt = Ether(
                src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
            ) / p.scapy_tra_sa.encrypt(
                IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                seq_num=0xFFFFFFFD,
            )
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            #
            # While in case A we cannot wrap the high sequence number again
            # because VPP will consider this packet to be one that moves the
            # window forward
            #
            pkt = Ether(
                src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
            ) / p.scapy_tra_sa.encrypt(
                IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                seq_num=0x200000999,
            )
            self.send_and_assert_no_replies(
                self.tra_if, [pkt], self.tra_if, timeout=0.2
            )

            hash_failed_count += 1
            self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)
            if hash_err != "":
                err = p.tra_sa_in.get_err(hash_err) + initial_sa_node_hash_diff
                self.assertEqual(err, hash_failed_count)

            #
            # but if we move the window forward to case B, then we can wrap
            # again
            #
            p.scapy_tra_sa.seq_num = 0x100000000 + anti_replay_window_size + 0x555
            pkt = Ether(
                src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
            ) / p.scapy_tra_sa.encrypt(
                IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                seq_num=p.scapy_tra_sa.seq_num,
            )
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            p.scapy_tra_sa.seq_num = 0x200000444
            pkt = Ether(
                src=self.tra_if.remote_mac, dst=self.tra_if.local_mac
            ) / p.scapy_tra_sa.encrypt(
                IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                seq_num=0x200000444,
            )
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

        else:
            #
            # without ESN TX sequence numbers can't wrap and packets are
            # dropped from here on out.
            #
            self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
            seq_cycle_count += len(pkts)
            self.assert_error_counter_equal(seq_cycle_node_name, seq_cycle_count)
            err = p.tra_sa_out.get_err("seq_cycled") + initial_sa_node_cycled_diff
            self.assertEqual(err, seq_cycle_count)

        # move the security-associations seq number on to the last we used
        self.vapi.cli("test ipsec sa %d seq 0x15f" % p.scapy_tra_sa_id)
        p.scapy_tra_sa.seq_num = 351
        p.vpp_tra_sa.seq_num = 351

    def verify_tra_lost(self):
        p = self.params[socket.AF_INET]
        esn_en = p.vpp_tra_sa.esn_en

        #
        # send packets with seq numbers 1->34
        # this means the window size is still in Case B (see RFC4303
        # Appendix A)
        #
        # for reasons i haven't investigated Scapy won't create a packet with
        # seq_num=0
        #
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(1, 3)
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        self.assertEqual(p.tra_sa_in.get_err("lost"), 0)

        # skip a sequence number
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(4, 6)
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        self.assertEqual(p.tra_sa_in.get_err("lost"), 0)

        # the lost packet are counted untill we get up past the first
        # sizeof(replay_window) packets
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(6, 100)
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        self.assertEqual(p.tra_sa_in.get_err("lost"), 1)

        # lost of holes in the sequence
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(100, 200, 2)
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if, n_rx=50)

        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(200, 300)
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        self.assertEqual(p.tra_sa_in.get_err("lost"), 51)

        # a big hole in the seq number space
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(400, 500)
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        self.assertEqual(p.tra_sa_in.get_err("lost"), 151)

    def verify_tra_basic4(self, count=1, payload_size=54):
        """ipsec v4 transport basic test"""
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")
        try:
            p = self.params[socket.AF_INET]
            send_pkts = self.gen_encrypt_pkts(
                p,
                p.scapy_tra_sa,
                self.tra_if,
                src=self.tra_if.remote_ip4,
                dst=self.tra_if.local_ip4,
                count=count,
                payload_size=payload_size,
            )
            recv_pkts = self.send_and_expect(self.tra_if, send_pkts, self.tra_if)
            for rx in recv_pkts:
                self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
                self.assert_packet_checksums_valid(rx)
                try:
                    decrypted = p.vpp_tra_sa.decrypt(rx[IP])
                    self.assert_packet_checksums_valid(decrypted)
                except:
                    self.logger.debug(ppp("Unexpected packet:", rx))
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))

        pkts = p.tra_sa_in.get_stats()["packets"]
        self.assertEqual(
            pkts, count, "incorrect SA in counts: expected %d != %d" % (count, pkts)
        )
        pkts = p.tra_sa_out.get_stats()["packets"]
        self.assertEqual(
            pkts, count, "incorrect SA out counts: expected %d != %d" % (count, pkts)
        )
        self.assertEqual(p.tra_sa_out.get_err("lost"), 0)
        self.assertEqual(p.tra_sa_in.get_err("lost"), 0)

        self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tra4_decrypt_node_name[0], count)

    def _verify_tra_anti_replay_algorithm_esn(self):
        def seq_num(seqh, seql):
            return (seqh << 32) | (seql & 0xFFFF_FFFF)

        p = self.params[socket.AF_INET]
        anti_replay_window_size = p.anti_replay_window_size

        seq_cycle_node_name = "/err/%s/seq_cycled" % self.tra4_encrypt_node_name
        replay_count = self.get_replay_counts(p)
        hash_failed_count = self.get_hash_failed_counts(p)
        seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)

        if ESP == self.encryption_type:
            undersize_node_name = "/err/%s/runt" % self.tra4_decrypt_node_name[0]
            undersize_count = self.statistics.get_err_counter(undersize_node_name)

        # reset the TX SA to avoid conflict with left configuration
        self.vapi.cli(f"test ipsec sa {p.vpp_tra_sa_id} seq 0x0")

        """
        RFC 4303 Appendix A2. Case A

        |: new Th marker
        a-i: possible seq num received
        +: Bl, Tl, Bl', Tl'
        [BT]l(sign) = [BT]l (sign) 2^32 mod 2^32 (Th inc/dec-remented by 1)

                Th - 1               Th                Th + 1
        --|--a--+---b---+-c--|--d--+---e---+-f--|--g--+---h---+--i-|--
                =========          =========          =========
                Bl-     Tl-        Bl      Tl         Bl+     Tl+

        Case A implies Tl >= W - 1
        """

        Th = 1
        Tl = anti_replay_window_size + 40
        Bl = Tl - anti_replay_window_size + 1

        # move VPP's RX AR window to Case A
        self.vapi.cli(f"test ipsec sa {p.scapy_tra_sa_id} seq {seq_num(Th, Tl):#x}")
        p.scapy_tra_sa.seq_num = seq_num(Th, Tl)

        """
        case a: Seql < Bl
            - pre-crypto check: algorithm predicts that the packet wrap the window
                -> Seqh = Th + 1
            - integrity check: should fail
            - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th - 1, Bl - 20), seq_num(Th - 1, Bl - 5))
        ]

        # out-of-window packets fail integrity check
        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case b: Bl <= Seql <= Tl
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> Seqh = Th
                    -> check for a replayed packet with Seql
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, Tl - 10), seq_num(Th, Tl - 5))
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        p.scapy_tra_sa.seq_num = seq_num(Th - 1, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th - 1, Tl - 35), seq_num(Th - 1, Tl - 5))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # some packets are rejected by the pre-crypto check
        replay_count += 5
        self.assertEqual(self.get_replay_counts(p), replay_count)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts) - 5
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case c: Seql > Tl
                - pre-crypto check: algorithm predicts that the packet does not wrap the window
                    -> Seqh = Th
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th - 1, Tl + 5), seq_num(Th - 1, Tl + 20))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case d: Seql < Bl
                - pre-crypto check: algorithm predicts that the packet wrap the window
                    -> Seqh = Th + 1
                - integrity check: should fail
                - post-crypto check: ...
        """
        p.scapy_tra_sa.seq_num = seq_num(Th, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, Bl - 20), seq_num(Th, Bl - 5))
        ]

        # out-of-window packets fail integrity check
        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case e: Bl <= Seql <= Tl
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> Seqh = Th
                    -> check for a replayed packet with Seql
                - integrity check: should pass
                - post-crypto check: should pass
                    -> Seql is marked in the AR window
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, Bl + 10), seq_num(Th, Bl + 30))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            case f: Seql > Tl
                - pre-crypto check: algorithm predicts that the packet does not wrap the window
                    -> Seqh = Th
                - integrity check: should pass
                - post-crypto check: should pass
                    -> AR window shift (the window stays Case A)
                    -> Seql is marked in the AR window
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, Tl + 50), seq_num(Th, Tl + 60))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            case g: Seql < Bl
                - pre-crypto check: algorithm predicts that the packet wrap the window
                    -> Seqh = Th + 1
                - integrity check: should pass
                - post-crypto check: should pass
                    -> AR window shift (may set the window in Case B)
                    -> Seql is marked in the AR window
        """
        p.scapy_tra_sa.seq_num = seq_num(Th + 1, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            # set the window in Case B (the minimum window size is 64
            # so we are sure to overlap)
            for seq in range(seq_num(Th + 1, 10), seq_num(Th + 1, 20))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # reset the VPP's RX AR window to Case A
        Th = 1
        Tl = 2 * anti_replay_window_size + 40
        Bl = Tl - anti_replay_window_size + 1

        self.vapi.cli(f"test ipsec sa {p.scapy_tra_sa_id} seq {seq_num(Th, Tl):#x}")

        p.scapy_tra_sa.seq_num = seq_num(Th + 1, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            # the AR will stay in Case A
            for seq in range(
                seq_num(Th + 1, anti_replay_window_size + 10),
                seq_num(Th + 1, anti_replay_window_size + 20),
            )
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            case h: Bl <= Seql <= Tl
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> Seqh = Th
                    -> check for a replayed packet with Seql
                - integrity check: the wrap is not detected, should fail
                - post-crypto check: ...
        """
        Th += 1
        Tl = anti_replay_window_size + 20
        Bl = Tl - anti_replay_window_size + 1

        p.scapy_tra_sa.seq_num = seq_num(Th + 1, Tl)

        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th + 1, Tl - 20), seq_num(Th + 1, Tl - 5))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # some packets are rejected by the pre-crypto check
        replay_count += 5
        self.assertEqual(self.get_replay_counts(p), replay_count)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts) - 5
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case i: Seql > Tl
                - pre-crypto check: algorithm predicts that the packet does not wrap the window
                    -> Seqh = Th
                - integrity check: the wrap is not detected, shoud fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th + 1, Tl + 5), seq_num(Th + 1, Tl + 15))
        ]

        # out-of-window packets fail integrity check
        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            RFC 4303 Appendix A2. Case B

                        Th - 1               Th                Th + 1
            ----|-a-+-----b----+--c--|-d-+----e-----+--f--|-g-+--h---
            =========          ===========          ===========
                    Tl-        Bl       Tl          Bl+       Tl+

            Case B implies Tl < W - 1
        """

        # reset the VPP's RX AR window to Case B
        Th = 2
        Tl = 30  # minimum window size of 64, we are sure to overlap
        Bl = (Tl - anti_replay_window_size + 1) % (1 << 32)

        self.vapi.cli(f"test ipsec sa {p.scapy_tra_sa_id} seq {seq_num(Th, Tl):#x}")
        p.scapy_tra_sa.seq_num = seq_num(Th, Tl)

        """
            case a: Seql <= Tl < Bl
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> Seqh = Th
                    -> check for replayed packet
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, 5), seq_num(Th, 10))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        p.scapy_tra_sa.seq_num = seq_num(Th - 1, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th - 1, 0), seq_num(Th - 1, 15))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # some packets are rejected by the pre-crypto check
        replay_count += 5
        self.assertEqual(self.get_replay_counts(p), replay_count)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts) - 5
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case b: Tl < Seql < Bl
                - pre-crypto check: algorithm predicts that the packet will shift the window
                    -> Seqh = Th
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th - 1, Tl + 10), seq_num(Th - 1, Tl + 20))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case c: Tl < Bl <= Seql
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> Seqh = Th - 1
                    -> check for a replayed packet with Seql
                - integrity check: should pass
                - post-crypto check: should pass
                    -> Seql is marked in the AR window
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th - 1, Bl + 10), seq_num(Th - 1, Bl + 20))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            case d: Seql <= Tl < Bl
                - pre-crypto check: algorithm predicts that the packet is the window
                    -> Seqh = Th
                    -> check for replayed packet
                - integrity check: should pass
                - post-crypto check: should pass
                    -> Seql is marked in the AR window
        """
        p.scapy_tra_sa.seq_num = seq_num(Th, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, 15), seq_num(Th, 25))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            case e: Tl < Seql < Bl
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> Seqh = Th
                    -> check for a replayed packet with Seql
                - integrity check: should pass
                - post-crypto check: should pass
                    -> AR window shift (may set the window in Case A)
                    -> Seql is marked in the AR window
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, Tl + 5), seq_num(Th, Tl + 15))
        ]

        # the window stays in Case B
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(
                seq_num(Th, Tl + anti_replay_window_size + 5),
                seq_num(Th, Tl + anti_replay_window_size + 15),
            )
        ]

        # the window moves to Case A
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # reset the VPP's RX AR window to Case B
        Th = 2
        Tl = 30  # minimum window size of 64, we are sure to overlap
        Bl = (Tl - anti_replay_window_size + 1) % (1 << 32)

        self.vapi.cli(f"test ipsec sa {p.scapy_tra_sa_id} seq {seq_num(Th, Tl):#x}")
        p.scapy_tra_sa.seq_num = seq_num(Th, Tl)

        """
            case f: Tl < Bl <= Seql
                - pre-crypto check: algorithm predicts that the packet is in the previous window
                    -> Seqh = Th - 1
                    -> check for a replayed packet with Seql
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, Bl + 10), seq_num(Th, Bl + 20))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case g: Seql <= Tl < Bl
                - pre-crypto check: algorithm predicts that the packet is the window
                    -> Seqh = Th
                    -> check for replayed packet
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th, 10), seq_num(Th, 15))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        p.scapy_tra_sa.seq_num = seq_num(Th + 1, Tl)
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th + 1, 0), seq_num(Th + 1, 15))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # some packets are rejected by the pre-crypto check
        replay_count += 5
        self.assertEqual(self.get_replay_counts(p), replay_count)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts) - 5
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

        """
            case h: Tl < Seql < Bl
                - pre-crypto check: algorithm predicts that the packet will shift the window
                    -> Seqh = Th
                - integrity check: should fail
                - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Th + 1, Tl + 10), seq_num(Th + 1, Tl + 20))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # out-of-window packets fail integrity check
        hash_failed_count += len(pkts)
        self.assertEqual(self.get_hash_failed_counts(p), hash_failed_count)

    def _verify_tra_anti_replay_algorithm_no_esn(self):
        def seq_num(seql):
            return seql & 0xFFFF_FFFF

        p = self.params[socket.AF_INET]
        anti_replay_window_size = p.anti_replay_window_size

        seq_cycle_node_name = "/err/%s/seq_cycled" % self.tra4_encrypt_node_name
        replay_count = self.get_replay_counts(p)
        hash_failed_count = self.get_hash_failed_counts(p)
        seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)

        if ESP == self.encryption_type:
            undersize_node_name = "/err/%s/runt" % self.tra4_decrypt_node_name[0]
            undersize_count = self.statistics.get_err_counter(undersize_node_name)

        # reset the TX SA to avoid conflict with left configuration
        self.vapi.cli(f"test ipsec sa {p.vpp_tra_sa_id} seq 0x0")

        """
        RFC 4303 Appendix A2. Case A

        a-c: possible seq num received
        +: Bl, Tl

        |--a--+---b---+-c--|
              =========
              Bl      Tl

        No ESN implies Th = 0
        Case A implies Tl >= W - 1
        """

        Tl = anti_replay_window_size + 40
        Bl = Tl - anti_replay_window_size + 1

        # move VPP's RX AR window to Case A
        self.vapi.cli(f"test ipsec sa {p.scapy_tra_sa_id} seq {seq_num(Tl):#x}")
        p.scapy_tra_sa.seq_num = seq_num(Tl)

        """
        case a: Seql < Bl
            - pre-crypto check: algorithm predicts that the packet is out of window
                -> packet should be dropped
            - integrity check: ...
            - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Bl - 20), seq_num(Bl - 5))
        ]

        # out-of-window packets
        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)
        replay_count += len(pkts)
        self.assertEqual(self.get_replay_counts(p), replay_count)

        """
            case b: Bl <= Seql <= Tl
                - pre-crypto check: algorithm predicts that the packet is in the window
                    -> check for a replayed packet with Seql
                - integrity check: should pass
                - post-crypto check:
                    -> check for a replayed packet with Seql
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Tl - 50), seq_num(Tl - 30))
        ]
        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Tl - 35), seq_num(Tl - 30))
        ]

        self.send_and_assert_no_replies(self.tra_if, pkts, timeout=0.2)

        # replayed packets
        replay_count += 5
        self.assertEqual(self.get_replay_counts(p), replay_count)

        """
            case c: Seql > Tl
                - pre-crypto check: algorithm predicts that the packet will shift the window
                - integrity check: should pass
                - post-crypto check: should pass
                    -> AR window is shifted
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(Tl + 5), seq_num(Tl + 20))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            RFC 4303 Appendix A2. Case B

            |-a-----+------b-----|
            =========
                    Tl

            Case B implies Tl < W - 1
        """

        # reset the VPP's RX AR window to Case B
        Tl = 30  # minimum window size of 64, we are sure to overlap
        Bl = seq_num(Tl - anti_replay_window_size + 1)

        self.vapi.cli(f"test ipsec sa {p.scapy_tra_sa_id} seq {seq_num(Tl):#x}")

        """
        case a: Seql <= Tl < Bl
            - pre-crypto check: algorithm predicts that the packet is in the window
                -> check for replayed packet
            - integrity check: should fail
            - post-crypto check: ...
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(5), seq_num(10))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

        """
            case b: Tl < Seql < Bl
                - pre-crypto check: algorithm predicts that the packet will shift the window
                - integrity check: should pass
                - post-crypto check: should pass
                    -> AR window is shifted
        """
        pkts = [
            (
                Ether(src=self.tra_if.remote_mac, dst=self.tra_if.local_mac)
                / p.scapy_tra_sa.encrypt(
                    IP(src=self.tra_if.remote_ip4, dst=self.tra_if.local_ip4) / ICMP(),
                    seq_num=seq,
                )
            )
            for seq in range(seq_num(-50), seq_num(-20))
        ]

        self.send_and_expect(self.tra_if, pkts, self.tra_if)

    def verify_tra_anti_replay_algorithm(self):
        if self.params[socket.AF_INET].vpp_tra_sa.esn_en:
            self._verify_tra_anti_replay_algorithm_esn()
        else:
            self._verify_tra_anti_replay_algorithm_no_esn()


@unittest.skipIf(
    "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
)
class IpsecTra4Tests(IpsecTra4):
    """UT test methods for Transport v4"""

    def test_tra_anti_replay(self):
        """ipsec v4 transport anti-replay test"""
        self.verify_tra_anti_replay()

    def test_tra_anti_replay_algorithm(self):
        """ipsec v4 transport anti-replay algorithm test"""
        self.verify_tra_anti_replay_algorithm()

    def test_tra_lost(self):
        """ipsec v4 transport lost packet test"""
        self.verify_tra_lost()

    def test_tra_basic(self, count=1):
        """ipsec v4 transport basic test"""
        self.verify_tra_basic4(count=1)

    def test_tra_burst(self):
        """ipsec v4 transport burst test"""
        self.verify_tra_basic4(count=257)


class IpsecTra6(object):
    """verify methods for Transport v6"""

    def verify_tra_basic6(self, count=1, payload_size=54):
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")
        try:
            p = self.params[socket.AF_INET6]
            send_pkts = self.gen_encrypt_pkts6(
                p,
                p.scapy_tra_sa,
                self.tra_if,
                src=self.tra_if.remote_ip6,
                dst=self.tra_if.local_ip6,
                count=count,
                payload_size=payload_size,
            )
            recv_pkts = self.send_and_expect(self.tra_if, send_pkts, self.tra_if)
            for rx in recv_pkts:
                self.assertEqual(len(rx) - len(Ether()) - len(IPv6()), rx[IPv6].plen)
                try:
                    decrypted = p.vpp_tra_sa.decrypt(rx[IPv6])
                    self.assert_packet_checksums_valid(decrypted)
                except:
                    self.logger.debug(ppp("Unexpected packet:", rx))
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))

        pkts = p.tra_sa_in.get_stats()["packets"]
        self.assertEqual(
            pkts, count, "incorrect SA in counts: expected %d != %d" % (count, pkts)
        )
        pkts = p.tra_sa_out.get_stats()["packets"]
        self.assertEqual(
            pkts, count, "incorrect SA out counts: expected %d != %d" % (count, pkts)
        )
        self.assert_packet_counter_equal(self.tra6_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tra6_decrypt_node_name[0], count)

    def gen_encrypt_pkts_ext_hdrs6(
        self, sa, sw_intf, src, dst, count=1, payload_size=54
    ):
        return [
            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
            / sa.encrypt(
                IPv6(src=src, dst=dst)
                / ICMPv6EchoRequest(id=0, seq=1, data="X" * payload_size)
            )
            for i in range(count)
        ]

    def gen_pkts_ext_hdrs6(self, sw_intf, src, dst, count=1, payload_size=54):
        return [
            Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac)
            / IPv6(src=src, dst=dst)
            / IPv6ExtHdrHopByHop()
            / IPv6ExtHdrFragment(id=2, offset=200)
            / Raw(b"\xff" * 200)
            for i in range(count)
        ]

    def verify_tra_encrypted6(self, p, sa, rxs):
        decrypted = []
        for rx in rxs:
            self.assert_packet_checksums_valid(rx)
            try:
                decrypt_pkt = p.vpp_tra_sa.decrypt(rx[IPv6])
                decrypted.append(decrypt_pkt)
                self.assert_equal(decrypt_pkt.src, self.tra_if.local_ip6)
                self.assert_equal(decrypt_pkt.dst, self.tra_if.remote_ip6)
            except:
                self.logger.debug(ppp("Unexpected packet:", rx))
                try:
                    self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
                except:
                    pass
                raise
        return decrypted

    def verify_tra_66_ext_hdrs(self, p):
        count = 63

        #
        # check we can decrypt with options
        #
        tx = self.gen_encrypt_pkts_ext_hdrs6(
            p.scapy_tra_sa,
            self.tra_if,
            src=self.tra_if.remote_ip6,
            dst=self.tra_if.local_ip6,
            count=count,
        )
        self.send_and_expect(self.tra_if, tx, self.tra_if)

        #
        # injecting a packet from ourselves to be routed of box is a hack
        # but it matches an outbout policy, alors je ne regrette rien
        #

        # one extension before ESP
        tx = (
            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
            / IPv6(src=self.tra_if.local_ip6, dst=self.tra_if.remote_ip6)
            / IPv6ExtHdrFragment(id=2, offset=200)
            / Raw(b"\xff" * 200)
        )

        rxs = self.send_and_expect(self.pg2, [tx], self.tra_if)
        dcs = self.verify_tra_encrypted6(p, p.vpp_tra_sa, rxs)

        for dc in dcs:
            # for reasons i'm not going to investigate scapy does not
            # created the correct headers after decrypt. but reparsing
            # the ipv6 packet fixes it
            dc = IPv6(raw(dc[IPv6]))
            self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)

        # two extensions before ESP
        tx = (
            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
            / IPv6(src=self.tra_if.local_ip6, dst=self.tra_if.remote_ip6)
            / IPv6ExtHdrHopByHop()
            / IPv6ExtHdrFragment(id=2, offset=200)
            / Raw(b"\xff" * 200)
        )

        rxs = self.send_and_expect(self.pg2, [tx], self.tra_if)
        dcs = self.verify_tra_encrypted6(p, p.vpp_tra_sa, rxs)

        for dc in dcs:
            dc = IPv6(raw(dc[IPv6]))
            self.assertTrue(dc[IPv6ExtHdrHopByHop])
            self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)

        # two extensions before ESP, one after
        tx = (
            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
            / IPv6(src=self.tra_if.local_ip6, dst=self.tra_if.remote_ip6)
            / IPv6ExtHdrHopByHop()
            / IPv6ExtHdrFragment(id=2, offset=200)
            / IPv6ExtHdrDestOpt()
            / Raw(b"\xff" * 200)
        )

        rxs = self.send_and_expect(self.pg2, [tx], self.tra_if)
        dcs = self.verify_tra_encrypted6(p, p.vpp_tra_sa, rxs)

        for dc in dcs:
            dc = IPv6(raw(dc[IPv6]))
            self.assertTrue(dc[IPv6ExtHdrDestOpt])
            self.assertTrue(dc[IPv6ExtHdrHopByHop])
            self.assert_equal(dc[IPv6ExtHdrFragment].id, 2)


@unittest.skipIf(
    "ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
)
class IpsecTra6Tests(IpsecTra6):
    """UT test methods for Transport v6"""

    def test_tra_basic6(self):
        """ipsec v6 transport basic test"""
        self.verify_tra_basic6(count=1)

    def test_tra_burst6(self):
        """ipsec v6 transport burst test"""
        self.verify_tra_basic6(count=257)


class IpsecTra6ExtTests(IpsecTra6):
    def test_tra_ext_hdrs_66(self):
        """ipsec 6o6 tra extension headers test"""
        self.verify_tra_66_ext_hdrs(self.params[socket.AF_INET6])


class IpsecTra46Tests(IpsecTra4Tests, IpsecTra6Tests):
    """UT test methods for Transport v6 and v4"""

    pass


class IpsecTun4(object):
    """verify methods for Tunnel v4"""

    def verify_counters4(self, p, count, n_frags=None, worker=None):
        if not n_frags:
            n_frags = count
        if hasattr(p, "spd_policy_in_any"):
            pkts = p.spd_policy_in_any.get_stats(worker)["packets"]
            self.assertEqual(
                pkts,
                count,
                "incorrect SPD any policy: expected %d != %d" % (count, pkts),
            )

        if hasattr(p, "tun_sa_in"):
            pkts = p.tun_sa_in.get_stats(worker)["packets"]
            self.assertEqual(
                pkts, count, "incorrect SA in counts: expected %d != %d" % (count, pkts)
            )
            pkts = p.tun_sa_out.get_stats(worker)["packets"]
            self.assertEqual(
                pkts,
                n_frags,
                "incorrect SA out counts: expected %d != %d" % (count, pkts),
            )

        self.assert_packet_counter_equal(self.tun4_encrypt_node_name, n_frags)
        self.assert_packet_counter_equal(self.tun4_decrypt_node_name[0], count)

    def verify_decrypted(self, p, rxs):
        for rx in rxs:
            self.assert_equal(rx[IP].src, p.remote_tun_if_host)
            self.assert_equal(rx[IP].dst, self.pg1.remote_ip4)
            self.assert_packet_checksums_valid(rx)

    def verify_esp_padding(self, sa, esp_payload, decrypt_pkt):
        align = sa.crypt_algo.block_size
        if align < 4:
            align = 4
        exp_len = (len(decrypt_pkt) + 2 + (align - 1)) & ~(align - 1)
        exp_len += sa.crypt_algo.iv_size
        exp_len += sa.crypt_algo.icv_size or sa.auth_algo.icv_size
        self.assertEqual(exp_len, len(esp_payload))

    def verify_encrypted(self, p, sa, rxs):
        decrypt_pkts = []
        for rx in rxs:
            if p.nat_header:
                self.assertEqual(rx[UDP].dport, p.nat_header.dport)
            self.assert_packet_checksums_valid(rx)
            self.assertEqual(len(rx) - len(Ether()), rx[IP].len)
            try:
                rx_ip = rx[IP]
                decrypt_pkt = p.vpp_tun_sa.decrypt(rx_ip)
                if not decrypt_pkt.haslayer(IP):
                    decrypt_pkt = IP(decrypt_pkt[Raw].load)
                if rx_ip.proto == socket.IPPROTO_ESP:
                    self.verify_esp_padding(sa, rx_ip[ESP].data, decrypt_pkt)
                decrypt_pkts.append(decrypt_pkt)
                self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
                self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
            except:
                self.logger.debug(ppp("Unexpected packet:", rx))
                try:
                    self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
                except:
                    pass
                raise
        pkts = reassemble4(decrypt_pkts)
        for pkt in pkts:
            self.assert_packet_checksums_valid(pkt)

    def verify_tun_44(self, p, count=1, payload_size=64, n_rx=None):
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec counters")
        self.vapi.cli("clear ipsec sa")
        if not n_rx:
            n_rx = count
        try:
            send_pkts = self.gen_encrypt_pkts(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host,
                dst=self.pg1.remote_ip4,
                count=count,
                payload_size=payload_size,
            )
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
            self.verify_decrypted(p, recv_pkts)

            send_pkts = self.gen_pkts(
                self.pg1,
                src=self.pg1.remote_ip4,
                dst=p.remote_tun_if_host,
                count=count,
                payload_size=payload_size,
            )
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if, n_rx)
            self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)

            for rx in recv_pkts:
                self.assertEqual(rx[IP].src, p.tun_src)
                self.assertEqual(rx[IP].dst, p.tun_dst)

        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))

        self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
        self.logger.info(self.vapi.ppcli("show ipsec sa 4"))
        self.verify_counters4(p, count, n_rx)

    def verify_tun_dropped_44(self, p, count=1, payload_size=64, n_rx=None):
        self.vapi.cli("clear errors")
        if not n_rx:
            n_rx = count
        try:
            send_pkts = self.gen_encrypt_pkts(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host,
                dst=self.pg1.remote_ip4,
                count=count,
            )
            self.send_and_assert_no_replies(self.tun_if, send_pkts)

            send_pkts = self.gen_pkts(
                self.pg1,
                src=self.pg1.remote_ip4,
                dst=p.remote_tun_if_host,
                count=count,
                payload_size=payload_size,
            )
            self.send_and_assert_no_replies(self.pg1, send_pkts)

        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))

    def verify_tun_reass_44(self, p):
        self.vapi.cli("clear errors")
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.tun_if.sw_if_index, enable_ip4=True
        )

        try:
            send_pkts = self.gen_encrypt_pkts(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host,
                dst=self.pg1.remote_ip4,
                payload_size=1900,
                count=1,
            )
            send_pkts = fragment_rfc791(send_pkts[0], 1400)
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1, n_rx=1)
            self.verify_decrypted(p, recv_pkts)

            send_pkts = self.gen_pkts(
                self.pg1, src=self.pg1.remote_ip4, dst=p.remote_tun_if_host, count=1
            )
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)

        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))

        self.verify_counters4(p, 1, 1)
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.tun_if.sw_if_index, enable_ip4=False
        )

    def verify_tun_64(self, p, count=1):
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")
        try:
            send_pkts = self.gen_encrypt_pkts6(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host6,
                dst=self.pg1.remote_ip6,
                count=count,
            )
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
            for recv_pkt in recv_pkts:
                self.assert_equal(recv_pkt[IPv6].src, p.remote_tun_if_host6)
                self.assert_equal(recv_pkt[IPv6].dst, self.pg1.remote_ip6)
                self.assert_packet_checksums_valid(recv_pkt)
            send_pkts = self.gen_pkts6(
                p,
                self.pg1,
                src=self.pg1.remote_ip6,
                dst=p.remote_tun_if_host6,
                count=count,
            )
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            for recv_pkt in recv_pkts:
                try:
                    decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IP])
                    if not decrypt_pkt.haslayer(IPv6):
                        decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
                    self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
                    self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host6)
                    self.assert_packet_checksums_valid(decrypt_pkt)
                except:
                    self.logger.error(ppp("Unexpected packet:", recv_pkt))
                    try:
                        self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
                    except:
                        pass
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))

        self.verify_counters4(p, count)

    def verify_keepalive(self, p):
        # the sizeof Raw is calculated to pad to the minimum ehternet
        # frame size of 64 btyes
        pkt = (
            Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac)
            / IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4)
            / UDP(sport=333, dport=4500)
            / Raw(b"\xff")
            / Padding(0 * 21)
        )
        self.send_and_assert_no_replies(self.tun_if, pkt * 31)
        self.assert_error_counter_equal(
            "/err/%s/nat_keepalive" % self.tun4_input_node, 31
        )

        pkt = (
            Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac)
            / IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4)
            / UDP(sport=333, dport=4500)
            / Raw(b"\xfe")
        )
        self.send_and_assert_no_replies(self.tun_if, pkt * 31)
        self.assert_error_counter_equal("/err/%s/too_short" % self.tun4_input_node, 31)

        pkt = (
            Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac)
            / IP(src=p.remote_tun_if_host, dst=self.tun_if.local_ip4)
            / UDP(sport=333, dport=4500)
            / Raw(b"\xfe")
            / Padding(0 * 21)
        )
        self.send_and_assert_no_replies(self.tun_if, pkt * 31)
        self.assert_error_counter_equal("/err/%s/too_short" % self.tun4_input_node, 62)


class IpsecTun4Tests(IpsecTun4):
    """UT test methods for Tunnel v4"""

    def test_tun_basic44(self):
        """ipsec 4o4 tunnel basic test"""
        self.verify_tun_44(self.params[socket.AF_INET], count=1)
        self.tun_if.admin_down()
        self.tun_if.resolve_arp()
        self.tun_if.admin_up()
        self.verify_tun_44(self.params[socket.AF_INET], count=1)

    def test_tun_reass_basic44(self):
        """ipsec 4o4 tunnel basic reassembly test"""
        self.verify_tun_reass_44(self.params[socket.AF_INET])

    def test_tun_burst44(self):
        """ipsec 4o4 tunnel burst test"""
        self.verify_tun_44(self.params[socket.AF_INET], count=127)


class IpsecTun6(object):
    """verify methods for Tunnel v6"""

    def verify_counters6(self, p_in, p_out, count, worker=None):
        if hasattr(p_in, "tun_sa_in"):
            pkts = p_in.tun_sa_in.get_stats(worker)["packets"]
            self.assertEqual(
                pkts, count, "incorrect SA in counts: expected %d != %d" % (count, pkts)
            )
        if hasattr(p_out, "tun_sa_out"):
            pkts = p_out.tun_sa_out.get_stats(worker)["packets"]
            self.assertEqual(
                pkts,
                count,
                "incorrect SA out counts: expected %d != %d" % (count, pkts),
            )
        self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tun6_decrypt_node_name[0], count)

    def verify_decrypted6(self, p, rxs):
        for rx in rxs:
            self.assert_equal(rx[IPv6].src, p.remote_tun_if_host)
            self.assert_equal(rx[IPv6].dst, self.pg1.remote_ip6)
            self.assert_packet_checksums_valid(rx)

    def verify_encrypted6(self, p, sa, rxs):
        for rx in rxs:
            self.assert_packet_checksums_valid(rx)
            self.assertEqual(len(rx) - len(Ether()) - len(IPv6()), rx[IPv6].plen)
            self.assert_equal(rx[IPv6].hlim, p.outer_hop_limit)
            if p.outer_flow_label:
                self.assert_equal(rx[IPv6].fl, p.outer_flow_label)
            try:
                decrypt_pkt = p.vpp_tun_sa.decrypt(rx[IPv6])
                if not decrypt_pkt.haslayer(IPv6):
                    decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
                self.assert_packet_checksums_valid(decrypt_pkt)
                self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
                self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
                self.assert_equal(decrypt_pkt.hlim, p.inner_hop_limit - 1)
                self.assert_equal(decrypt_pkt.fl, p.inner_flow_label)
            except:
                self.logger.debug(ppp("Unexpected packet:", rx))
                try:
                    self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
                except:
                    pass
                raise

    def verify_drop_tun_tx_66(self, p_in, count=1, payload_size=64):
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")

        send_pkts = self.gen_pkts6(
            p_in,
            self.pg1,
            src=self.pg1.remote_ip6,
            dst=p_in.remote_tun_if_host,
            count=count,
            payload_size=payload_size,
        )
        self.send_and_assert_no_replies(self.tun_if, send_pkts)
        self.logger.info(self.vapi.cli("sh punt stats"))

    def verify_drop_tun_rx_66(self, p_in, count=1, payload_size=64):
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")

        send_pkts = self.gen_encrypt_pkts6(
            p_in,
            p_in.scapy_tun_sa,
            self.tun_if,
            src=p_in.remote_tun_if_host,
            dst=self.pg1.remote_ip6,
            count=count,
        )
        self.send_and_assert_no_replies(self.tun_if, send_pkts)

    def verify_drop_tun_66(self, p_in, count=1, payload_size=64):
        self.verify_drop_tun_tx_66(p_in, count=count, payload_size=payload_size)
        self.verify_drop_tun_rx_66(p_in, count=count, payload_size=payload_size)

    def verify_tun_66(self, p_in, p_out=None, count=1, payload_size=64):
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")
        if not p_out:
            p_out = p_in
        try:
            send_pkts = self.gen_encrypt_pkts6(
                p_in,
                p_in.scapy_tun_sa,
                self.tun_if,
                src=p_in.remote_tun_if_host,
                dst=self.pg1.remote_ip6,
                count=count,
                payload_size=payload_size,
            )
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
            self.verify_decrypted6(p_in, recv_pkts)

            send_pkts = self.gen_pkts6(
                p_in,
                self.pg1,
                src=self.pg1.remote_ip6,
                dst=p_out.remote_tun_if_host,
                count=count,
                payload_size=payload_size,
            )
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            self.verify_encrypted6(p_out, p_out.vpp_tun_sa, recv_pkts)

            for rx in recv_pkts:
                self.assertEqual(rx[IPv6].src, p_out.tun_src)
                self.assertEqual(rx[IPv6].dst, p_out.tun_dst)

        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))
        self.verify_counters6(p_in, p_out, count)

    def verify_tun_reass_66(self, p):
        self.vapi.cli("clear errors")
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.tun_if.sw_if_index, enable_ip6=True
        )

        try:
            send_pkts = self.gen_encrypt_pkts6(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host,
                dst=self.pg1.remote_ip6,
                count=1,
                payload_size=1850,
            )
            send_pkts = fragment_rfc8200(send_pkts[0], 1, 1400, self.logger)
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1, n_rx=1)
            self.verify_decrypted6(p, recv_pkts)

            send_pkts = self.gen_pkts6(
                p,
                self.pg1,
                src=self.pg1.remote_ip6,
                dst=p.remote_tun_if_host,
                count=1,
                payload_size=64,
            )
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            self.verify_encrypted6(p, p.vpp_tun_sa, recv_pkts)
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))
        self.verify_counters6(p, p, 1)
        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.tun_if.sw_if_index, enable_ip6=False
        )

    def verify_tun_46(self, p, count=1):
        """ipsec 4o6 tunnel basic test"""
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")
        try:
            send_pkts = self.gen_encrypt_pkts(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host4,
                dst=self.pg1.remote_ip4,
                count=count,
            )
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
            for recv_pkt in recv_pkts:
                self.assert_equal(recv_pkt[IP].src, p.remote_tun_if_host4)
                self.assert_equal(recv_pkt[IP].dst, self.pg1.remote_ip4)
                self.assert_packet_checksums_valid(recv_pkt)
            send_pkts = self.gen_pkts(
                self.pg1,
                src=self.pg1.remote_ip4,
                dst=p.remote_tun_if_host4,
                count=count,
            )
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            for recv_pkt in recv_pkts:
                try:
                    decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IPv6])
                    if not decrypt_pkt.haslayer(IP):
                        decrypt_pkt = IP(decrypt_pkt[Raw].load)
                    self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
                    self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host4)
                    self.assert_packet_checksums_valid(decrypt_pkt)
                except:
                    self.logger.debug(ppp("Unexpected packet:", recv_pkt))
                    try:
                        self.logger.debug(ppp("Decrypted packet:", decrypt_pkt))
                    except:
                        pass
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec all"))
        self.verify_counters6(p, p, count)

    def verify_keepalive(self, p):
        # the sizeof Raw is calculated to pad to the minimum ehternet
        # frame size of 64 btyes
        pkt = (
            Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac)
            / IPv6(src=p.remote_tun_if_host, dst=self.tun_if.local_ip6)
            / UDP(sport=333, dport=4500)
            / Raw(b"\xff")
            / Padding(0 * 1)
        )
        self.send_and_assert_no_replies(self.tun_if, pkt * 31)
        self.assert_error_counter_equal(
            "/err/%s/nat_keepalive" % self.tun6_input_node, 31
        )

        pkt = (
            Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac)
            / IPv6(src=p.remote_tun_if_host, dst=self.tun_if.local_ip6)
            / UDP(sport=333, dport=4500)
            / Raw(b"\xfe")
        )
        self.send_and_assert_no_replies(self.tun_if, pkt * 31)
        self.assert_error_counter_equal("/err/%s/too_short" % self.tun6_input_node, 31)

        pkt = (
            Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac)
            / IPv6(src=p.remote_tun_if_host, dst=self.tun_if.local_ip6)
            / UDP(sport=333, dport=4500)
            / Raw(b"\xfe")
            / Padding(0 * 21)
        )
        self.send_and_assert_no_replies(self.tun_if, pkt * 31)
        self.assert_error_counter_equal("/err/%s/too_short" % self.tun6_input_node, 62)


class IpsecTun6Tests(IpsecTun6):
    """UT test methods for Tunnel v6"""

    def test_tun_basic66(self):
        """ipsec 6o6 tunnel basic test"""
        self.verify_tun_66(self.params[socket.AF_INET6], count=1)

    def test_tun_reass_basic66(self):
        """ipsec 6o6 tunnel basic reassembly test"""
        self.verify_tun_reass_66(self.params[socket.AF_INET6])

    def test_tun_burst66(self):
        """ipsec 6o6 tunnel burst test"""
        self.verify_tun_66(self.params[socket.AF_INET6], count=257)


class IpsecTun6HandoffTests(IpsecTun6):
    """UT test methods for Tunnel v6 with multiple workers"""

    vpp_worker_count = 2

    def test_tun_handoff_66(self):
        """ipsec 6o6 tunnel worker hand-off test"""
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")

        N_PKTS = 15
        p = self.params[socket.AF_INET6]

        # inject alternately on worker 0 and 1. all counts on the SA
        # should be against worker 0
        for worker in [0, 1, 0, 1]:
            send_pkts = self.gen_encrypt_pkts6(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host,
                dst=self.pg1.remote_ip6,
                count=N_PKTS,
            )
            recv_pkts = self.send_and_expect(
                self.tun_if, send_pkts, self.pg1, worker=worker
            )
            self.verify_decrypted6(p, recv_pkts)

            send_pkts = self.gen_pkts6(
                p,
                self.pg1,
                src=self.pg1.remote_ip6,
                dst=p.remote_tun_if_host,
                count=N_PKTS,
            )
            recv_pkts = self.send_and_expect(
                self.pg1, send_pkts, self.tun_if, worker=worker
            )
            self.verify_encrypted6(p, p.vpp_tun_sa, recv_pkts)

        # all counts against the first worker that was used
        self.verify_counters6(p, p, 4 * N_PKTS, worker=0)


class IpsecTun4HandoffTests(IpsecTun4):
    """UT test methods for Tunnel v4 with multiple workers"""

    vpp_worker_count = 2

    def test_tun_handooff_44(self):
        """ipsec 4o4 tunnel worker hand-off test"""
        self.vapi.cli("clear errors")
        self.vapi.cli("clear ipsec sa")

        N_PKTS = 15
        p = self.params[socket.AF_INET]

        # inject alternately on worker 0 and 1. all counts on the SA
        # should be against worker 0
        for worker in [0, 1, 0, 1]:
            send_pkts = self.gen_encrypt_pkts(
                p,
                p.scapy_tun_sa,
                self.tun_if,
                src=p.remote_tun_if_host,
                dst=self.pg1.remote_ip4,
                count=N_PKTS,
            )
            recv_pkts = self.send_and_expect(
                self.tun_if, send_pkts, self.pg1, worker=worker
            )
            self.verify_decrypted(p, recv_pkts)

            send_pkts = self.gen_pkts(
                self.pg1,
                src=self.pg1.remote_ip4,
                dst=p.remote_tun_if_host,
                count=N_PKTS,
            )
            recv_pkts = self.send_and_expect(
                self.pg1, send_pkts, self.tun_if, worker=worker
            )
            self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts)

        # all counts against the first worker that was used
        self.verify_counters4(p, 4 * N_PKTS, worker=0)


class IpsecTun46Tests(IpsecTun4Tests, IpsecTun6Tests):
    """UT test methods for Tunnel v6 & v4"""

    pass


class IPSecIPv4Fwd(VppTestCase):
    """Test IPSec by capturing and verifying IPv4 forwarded pkts"""

    @classmethod
    def setUpConstants(cls):
        super(IPSecIPv4Fwd, cls).setUpConstants()

    def setUp(self):
        super(IPSecIPv4Fwd, self).setUp()
        # store SPD objects so we can remove configs on tear down
        self.spd_objs = []
        self.spd_policies = []

    def tearDown(self):
        # remove SPD policies
        for obj in self.spd_policies:
            obj.remove_vpp_config()
        self.spd_policies = []
        # remove SPD items (interface bindings first, then SPD)
        for obj in reversed(self.spd_objs):
            obj.remove_vpp_config()
        self.spd_objs = []
        # close down pg intfs
        for pg in self.pg_interfaces:
            pg.unconfig_ip4()
            pg.admin_down()
        super(IPSecIPv4Fwd, self).tearDown()

    def create_interfaces(self, num_ifs=2):
        # create interfaces pg0 ... pg<num_ifs>
        self.create_pg_interfaces(range(num_ifs))
        for pg in self.pg_interfaces:
            # put the interface up
            pg.admin_up()
            # configure IPv4 address on the interface
            pg.config_ip4()
            # resolve ARP, so that we know VPP MAC
            pg.resolve_arp()
        self.logger.info(self.vapi.ppcli("show int addr"))

    def spd_create_and_intf_add(self, spd_id, pg_list):
        spd = VppIpsecSpd(self, spd_id)
        spd.add_vpp_config()
        self.spd_objs.append(spd)
        for pg in pg_list:
            spdItf = VppIpsecSpdItfBinding(self, spd, pg)
            spdItf.add_vpp_config()
            self.spd_objs.append(spdItf)

    def get_policy(self, policy_type):
        e = VppEnum.vl_api_ipsec_spd_action_t
        if policy_type == "protect":
            return e.IPSEC_API_SPD_ACTION_PROTECT
        elif policy_type == "bypass":
            return e.IPSEC_API_SPD_ACTION_BYPASS
        elif policy_type == "discard":
            return e.IPSEC_API_SPD_ACTION_DISCARD
        else:
            raise Exception("Invalid policy type: %s", policy_type)

    def spd_add_rem_policy(
        self,
        spd_id,
        src_if,
        dst_if,
        proto,
        is_out,
        priority,
        policy_type,
        remove=False,
        all_ips=False,
        ip_range=False,
        local_ip_start=ip_address("0.0.0.0"),
        local_ip_stop=ip_address("255.255.255.255"),
        remote_ip_start=ip_address("0.0.0.0"),
        remote_ip_stop=ip_address("255.255.255.255"),
        remote_port_start=0,
        remote_port_stop=65535,
        local_port_start=0,
        local_port_stop=65535,
    ):
        spd = VppIpsecSpd(self, spd_id)

        if all_ips:
            src_range_low = ip_address("0.0.0.0")
            src_range_high = ip_address("255.255.255.255")
            dst_range_low = ip_address("0.0.0.0")
            dst_range_high = ip_address("255.255.255.255")

        elif ip_range:
            src_range_low = local_ip_start
            src_range_high = local_ip_stop
            dst_range_low = remote_ip_start
            dst_range_high = remote_ip_stop

        else:
            src_range_low = src_if.remote_ip4
            src_range_high = src_if.remote_ip4
            dst_range_low = dst_if.remote_ip4
            dst_range_high = dst_if.remote_ip4

        spdEntry = VppIpsecSpdEntry(
            self,
            spd,
            0,
            src_range_low,
            src_range_high,
            dst_range_low,
            dst_range_high,
            proto,
            priority=priority,
            policy=self.get_policy(policy_type),
            is_outbound=is_out,
            remote_port_start=remote_port_start,
            remote_port_stop=remote_port_stop,
            local_port_start=local_port_start,
            local_port_stop=local_port_stop,
        )

        if remove is False:
            spdEntry.add_vpp_config()
            self.spd_policies.append(spdEntry)
        else:
            spdEntry.remove_vpp_config()
            self.spd_policies.remove(spdEntry)
        self.logger.info(self.vapi.ppcli("show ipsec all"))
        return spdEntry

    def create_stream(
        self, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=5678, proto="UDP"
    ):
        packets = []
        # create SA
        sa = SecurityAssociation(
            ESP,
            spi=1000,
            crypt_algo="AES-CBC",
            crypt_key=b"JPjyOWBeVEQiMe7h",
            auth_algo="HMAC-SHA1-96",
            auth_key=b"C91KUR9GYMm5GfkEvNjX",
            tunnel_header=IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4),
            nat_t_header=UDP(sport=src_prt, dport=dst_prt),
        )
        for i in range(pkt_count):
            # create packet info stored in the test case instance
            info = self.create_packet_info(src_if, dst_if)
            # convert the info into packet payload
            payload = self.info_to_payload(info)
            # create the packet itself
            p = []
            if proto == "UDP-ESP":
                p = Ether(dst=src_if.local_mac, src=src_if.remote_mac) / sa.encrypt(
                    IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
                    / UDP(sport=src_prt, dport=dst_prt)
                    / Raw(payload)
                )
            elif proto == "UDP":
                p = (
                    Ether(dst=src_if.local_mac, src=src_if.remote_mac)
                    / IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
                    / UDP(sport=src_prt, dport=dst_prt)
                    / Raw(payload)
                )
            elif proto == "TCP":
                p = (
                    Ether(dst=src_if.local_mac, src=src_if.remote_mac)
                    / IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4)
                    / TCP(sport=src_prt, dport=dst_prt)
                    / Raw(payload)
                )
            # store a copy of the packet in the packet info
            info.data = p.copy()
            # append the packet to the list
            packets.append(p)
        # return the created packet list
        return packets

    def verify_capture(self, src_if, dst_if, capture):
        packet_info = None
        for packet in capture:
            try:
                ip = packet[IP]
                udp = packet[UDP]
                # convert the payload to packet info object
                payload_info = self.payload_to_info(packet)
                # make sure the indexes match
                self.assert_equal(
                    payload_info.src, src_if.sw_if_index, "source sw_if_index"
                )
                self.assert_equal(
                    payload_info.dst, dst_if.sw_if_index, "destination sw_if_index"
                )
                packet_info = self.get_next_packet_info_for_interface2(
                    src_if.sw_if_index, dst_if.sw_if_index, packet_info
                )
                # make sure we didn't run out of saved packets
                self.assertIsNotNone(packet_info)
                self.assert_equal(
                    payload_info.index, packet_info.index, "packet info index"
                )
                saved_packet = packet_info.data  # fetch the saved packet
                # assert the values match
                self.assert_equal(ip.src, saved_packet[IP].src, "IP source address")
                # ... more assertions here
                self.assert_equal(udp.sport, saved_packet[UDP].sport, "UDP source port")
            except Exception as e:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        remaining_packet = self.get_next_packet_info_for_interface2(
            src_if.sw_if_index, dst_if.sw_if_index, packet_info
        )
        self.assertIsNone(
            remaining_packet,
            "Interface %s: Packet expected from interface "
            "%s didn't arrive" % (dst_if.name, src_if.name),
        )

    def verify_policy_match(self, pkt_count, spdEntry):
        self.logger.info("XXXX %s %s", str(spdEntry), str(spdEntry.get_stats()))
        matched_pkts = spdEntry.get_stats().get("packets")
        self.logger.info("Policy %s matched: %d pkts", str(spdEntry), matched_pkts)
        self.assert_equal(pkt_count, matched_pkts)

    # Method verify_l3_l4_capture() will verify network and transport layer
    # fields of the packet sa.encrypt() gives interface number garbadge.
    # thus interface validation get failed (scapy bug?). However our intent
    # is to verify IP layer and above and that is covered.

    def verify_l3_l4_capture(
        self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=5678
    ):
        for packet in capture:
            try:
                self.assert_packet_checksums_valid(packet)
                self.assert_equal(
                    packet[IP].src,
                    src_if.remote_ip4,
                    "decrypted packet source address",
                )
                self.assert_equal(
                    packet[IP].dst,
                    dst_if.remote_ip4,
                    "decrypted packet destination address",
                )
                if packet.haslayer(TCP):
                    self.assertFalse(
                        packet.haslayer(UDP),
                        "unexpected UDP header in decrypted packet",
                    )
                elif packet.haslayer(UDP):
                    if packet[UDP].payload:
                        self.assertFalse(
                            packet[UDP][1].haslayer(UDP),
                            "unexpected UDP header in decrypted packet",
                        )
                else:
                    self.assertFalse(
                        packet.haslayer(UDP),
                        "unexpected UDP header in decrypted packet",
                    )
                    self.assert_equal(
                        packet[ICMP].id, self.icmp_id_in, "decrypted packet ICMP ID"
                    )
            except Exception:
                self.logger.error(ppp("Unexpected or invalid plain packet:", packet))
                raise


class SpdFlowCacheTemplate(IPSecIPv4Fwd):
    @classmethod
    def setUpConstants(cls):
        super(SpdFlowCacheTemplate, cls).setUpConstants()
        # Override this method with required cmdline parameters e.g.
        # cls.vpp_cmdline.extend(["ipsec", "{",
        #                         "ipv4-outbound-spd-flow-cache on",
        #                         "}"])
        # cls.logger.info("VPP modified cmdline is %s" % " "
        #                 .join(cls.vpp_cmdline))

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

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

    def get_spd_flow_cache_entries(self, outbound):
        """'show ipsec spd' output:
        ipv4-inbound-spd-flow-cache-entries: 0
        ipv4-outbound-spd-flow-cache-entries: 0
        """
        show_ipsec_reply = self.vapi.cli("show ipsec spd")
        # match the relevant section of 'show ipsec spd' output
        if outbound:
            regex_match = re.search(
                "ipv4-outbound-spd-flow-cache-entries: (.*)",
                show_ipsec_reply,
                re.DOTALL,
            )
        else:
            regex_match = re.search(
                "ipv4-inbound-spd-flow-cache-entries: (.*)", show_ipsec_reply, re.DOTALL
            )
        if regex_match is None:
            raise Exception(
                "Unable to find spd flow cache entries \
                in 'show ipsec spd' CLI output - regex failed to match"
            )
        else:
            try:
                num_entries = int(regex_match.group(1))
            except ValueError:
                raise Exception(
                    "Unable to get spd flow cache entries \
                from 'show ipsec spd' string: %s",
                    regex_match.group(0),
                )
            self.logger.info("%s", regex_match.group(0))
        return num_entries

    def verify_num_outbound_flow_cache_entries(self, expected_elements):
        self.assertEqual(
            self.get_spd_flow_cache_entries(outbound=True), expected_elements
        )

    def verify_num_inbound_flow_cache_entries(self, expected_elements):
        self.assertEqual(
            self.get_spd_flow_cache_entries(outbound=False), expected_elements
        )

    def crc32_supported(self):
        # lscpu is part of util-linux package, available on all Linux Distros
        stream = os.popen("lscpu")
        cpu_info = stream.read()
        # feature/flag "crc32" on Aarch64 and "sse4_2" on x86
        # see vppinfra/crc32.h
        if "crc32" or "sse4_2" in cpu_info:
            self.logger.info("\ncrc32 supported:\n" + cpu_info)
            return True
        else:
            self.logger.info("\ncrc32 NOT supported:\n" + cpu_info)
            return False

    def create_stream(
        cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=4500, proto="UDP-ESP"
    ):
        packets = []
        packets = super(SpdFlowCacheTemplate, cls).create_stream(
            src_if, dst_if, pkt_count, src_prt, dst_prt, proto
        )
        return packets

    def verify_capture(
        self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=4500
    ):
        super(SpdFlowCacheTemplate, self).verify_l3_l4_capture(
            src_if, dst_if, capture, tcp_port_in, udp_port_in
        )


class SpdFastPathTemplate(IPSecIPv4Fwd):
    @classmethod
    def setUpConstants(cls):
        super(SpdFastPathTemplate, cls).setUpConstants()
        # Override this method with required cmdline parameters e.g.
        # cls.vpp_cmdline.extend(["ipsec", "{",
        #                         "ipv4-outbound-spd-flow-cache on",
        #                         "}"])
        # cls.logger.info("VPP modified cmdline is %s" % " "
        #                 .join(cls.vpp_cmdline))

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

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

    def create_stream(
        cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=4500, proto="UDP-ESP"
    ):
        packets = []
        packets = super(SpdFastPathTemplate, cls).create_stream(
            src_if, dst_if, pkt_count, src_prt, dst_prt, proto
        )
        return packets

    def verify_capture(
        self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=4500
    ):
        super(SpdFastPathTemplate, self).verify_l3_l4_capture(
            src_if, dst_if, capture, tcp_port_in, udp_port_in
        )


class IpsecDefaultTemplate(IPSecIPv4Fwd):
    @classmethod
    def setUpConstants(cls):
        super(IpsecDefaultTemplate, cls).setUpConstants()

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

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

    def create_stream(
        cls, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=4500, proto="UDP-ESP"
    ):
        packets = []
        packets = super(IpsecDefaultTemplate, cls).create_stream(
            src_if, dst_if, pkt_count, src_prt, dst_prt, proto
        )
        return packets

    def verify_capture(
        self, src_if, dst_if, capture, tcp_port_in=1234, udp_port_in=4500
    ):
        super(IpsecDefaultTemplate, self).verify_l3_l4_capture(
            src_if, dst_if, capture, tcp_port_in, udp_port_in
        )


class IPSecIPv6Fwd(VppTestCase):
    """Test IPSec by capturing and verifying IPv6 forwarded pkts"""

    @classmethod
    def setUpConstants(cls):
        super(IPSecIPv6Fwd, cls).setUpConstants()

    def setUp(self):
        super(IPSecIPv6Fwd, self).setUp()
        # store SPD objects so we can remove configs on tear down
        self.spd_objs = []
        self.spd_policies = []

    def tearDown(self):
        # remove SPD policies
        for obj in self.spd_policies:
            obj.remove_vpp_config()
        self.spd_policies = []
        # remove SPD items (interface bindings first, then SPD)
        for obj in reversed(self.spd_objs):
            obj.remove_vpp_config()
        self.spd_objs = []
        # close down pg intfs
        for pg in self.pg_interfaces:
            pg.unconfig_ip6()
            pg.admin_down()
        super(IPSecIPv6Fwd, self).tearDown()

    def create_interfaces(self, num_ifs=2):
        # create interfaces pg0 ... pg<num_ifs>
        self.create_pg_interfaces(range(num_ifs))
        for pg in self.pg_interfaces:
            # put the interface up
            pg.admin_up()
            # configure IPv6 address on the interface
            pg.config_ip6()
            pg.resolve_ndp()
        self.logger.info(self.vapi.ppcli("show int addr"))

    def spd_create_and_intf_add(self, spd_id, pg_list):
        spd = VppIpsecSpd(self, spd_id)
        spd.add_vpp_config()
        self.spd_objs.append(spd)
        for pg in pg_list:
            spdItf = VppIpsecSpdItfBinding(self, spd, pg)
            spdItf.add_vpp_config()
            self.spd_objs.append(spdItf)

    def get_policy(self, policy_type):
        e = VppEnum.vl_api_ipsec_spd_action_t
        if policy_type == "protect":
            return e.IPSEC_API_SPD_ACTION_PROTECT
        elif policy_type == "bypass":
            return e.IPSEC_API_SPD_ACTION_BYPASS
        elif policy_type == "discard":
            return e.IPSEC_API_SPD_ACTION_DISCARD
        else:
            raise Exception("Invalid policy type: %s", policy_type)

    def spd_add_rem_policy(
        self,
        spd_id,
        src_if,
        dst_if,
        proto,
        is_out,
        priority,
        policy_type,
        remove=False,
        all_ips=False,
        ip_range=False,
        local_ip_start=ip_address("0::0"),
        local_ip_stop=ip_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
        remote_ip_start=ip_address("0::0"),
        remote_ip_stop=ip_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
        remote_port_start=0,
        remote_port_stop=65535,
        local_port_start=0,
        local_port_stop=65535,
    ):
        spd = VppIpsecSpd(self, spd_id)

        if all_ips:
            src_range_low = ip_address("0::0")
            src_range_high = ip_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
            dst_range_low = ip_address("0::0")
            dst_range_high = ip_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")

        elif ip_range:
            src_range_low = local_ip_start
            src_range_high = local_ip_stop
            dst_range_low = remote_ip_start
            dst_range_high = remote_ip_stop

        else:
            src_range_low = src_if.remote_ip6
            src_range_high = src_if.remote_ip6
            dst_range_low = dst_if.remote_ip6
            dst_range_high = dst_if.remote_ip6

        spdEntry = VppIpsecSpdEntry(
            self,
            spd,
            0,
            src_range_low,
            src_range_high,
            dst_range_low,
            dst_range_high,
            proto,
            priority=priority,
            policy=self.get_policy(policy_type),
            is_outbound=is_out,
            remote_port_start=remote_port_start,
            remote_port_stop=remote_port_stop,
            local_port_start=local_port_start,
            local_port_stop=local_port_stop,
        )

        if remove is False:
            spdEntry.add_vpp_config()
            self.spd_policies.append(spdEntry)
        else:
            spdEntry.remove_vpp_config()
            self.spd_policies.remove(spdEntry)
        self.logger.info(self.vapi.ppcli("show ipsec all"))
        return spdEntry

    def create_stream(self, src_if, dst_if, pkt_count, src_prt=1234, dst_prt=5678):
        packets = []
        for i in range(pkt_count):
            # create packet info stored in the test case instance
            info = self.create_packet_info(src_if, dst_if)
            # convert the info into packet payload
            payload = self.info_to_payload(info)
            # create the packet itself
            p = (
                Ether(dst=src_if.local_mac, src=src_if.remote_mac)
                / IPv6(src=src_if.remote_ip6, dst=dst_if.remote_ip6)
                / UDP(sport=src_prt, dport=dst_prt)
                / Raw(payload)
            )
            # store a copy of the packet in the packet info
            info.data = p.copy()
            # append the packet to the list
            packets.append(p)
        # return the created packet list
        return packets

    def verify_capture(self, src_if, dst_if, capture):
        packet_info = None
        for packet in capture:
            try:
                ip = packet[IPv6]
                udp = packet[UDP]
                # convert the payload to packet info object
                payload_info = self.payload_to_info(packet)
                # make sure the indexes match
                self.assert_equal(
                    payload_info.src, src_if.sw_if_index, "source sw_if_index"
                )
                self.assert_equal(
                    payload_info.dst, dst_if.sw_if_index, "destination sw_if_index"
                )
                packet_info = self.get_next_packet_info_for_interface2(
                    src_if.sw_if_index, dst_if.sw_if_index, packet_info
                )
                # make sure we didn't run out of saved packets
                self.assertIsNotNone(packet_info)
                self.assert_equal(
                    payload_info.index, packet_info.index, "packet info index"
                )
                saved_packet = packet_info.data  # fetch the saved packet
                # assert the values match
                self.assert_equal(ip.src, saved_packet[IPv6].src, "IP source address")
                # ... more assertions here
                self.assert_equal(udp.sport, saved_packet[UDP].sport, "UDP source port")
            except Exception as e:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        remaining_packet = self.get_next_packet_info_for_interface2(
            src_if.sw_if_index, dst_if.sw_if_index, packet_info
        )
        self.assertIsNone(
            remaining_packet,
            "Interface %s: Packet expected from interface "
            "%s didn't arrive" % (dst_if.name, src_if.name),
        )

    def verify_policy_match(self, pkt_count, spdEntry):
        self.logger.info("XXXX %s %s", str(spdEntry), str(spdEntry.get_stats()))
        matched_pkts = spdEntry.get_stats().get("packets")
        self.logger.info("Policy %s matched: %d pkts", str(spdEntry), matched_pkts)
        self.assert_equal(pkt_count, matched_pkts)


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