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


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)


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


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)


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)
