#!/usr/bin/env python

import unittest
import binascii
from socket import AF_INET6

from framework import VppTestCase, VppTestRunner
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
from vpp_srv6 import SRv6LocalSIDBehaviors, VppSRv6LocalSID, VppSRv6Policy, \
    SRv6PolicyType, VppSRv6Steering, SRv6PolicySteeringTypes

from scapy.packet import Raw
from scapy.layers.l2 import Ether, Dot1Q
from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting
from scapy.layers.inet import IP, UDP

from scapy.utils import inet_pton, inet_ntop

from util import ppp


class TestSRv6(VppTestCase):
    """ SRv6 Test Case """

    @classmethod
    def setUpClass(self):
        super(TestSRv6, self).setUpClass()

    def setUp(self):
        """ Perform test setup before each test case.
        """
        super(TestSRv6, self).setUp()

        # packet sizes, inclusive L2 overhead
        self.pg_packet_sizes = [64, 512, 1518, 9018]

        # reset packet_infos
        self.reset_packet_infos()

    def tearDown(self):
        """ Clean up test setup after each test case.
        """
        self.teardown_interfaces()

        super(TestSRv6, self).tearDown()

    def configure_interface(self,
                            interface,
                            ipv6=False, ipv4=False,
                            ipv6_table_id=0, ipv4_table_id=0):
        """ Configure interface.
        :param ipv6: configure IPv6 on interface
        :param ipv4: configure IPv4 on interface
        :param ipv6_table_id: FIB table_id for IPv6
        :param ipv4_table_id: FIB table_id for IPv4
        """
        self.logger.debug("Configuring interface %s" % (interface.name))
        if ipv6:
            self.logger.debug("Configuring IPv6")
            interface.set_table_ip6(ipv6_table_id)
            interface.config_ip6()
            interface.resolve_ndp(timeout=5)
        if ipv4:
            self.logger.debug("Configuring IPv4")
            interface.set_table_ip4(ipv4_table_id)
            interface.config_ip4()
            interface.resolve_arp()
        interface.admin_up()

    def setup_interfaces(self, ipv6=[], ipv4=[],
                         ipv6_table_id=[], ipv4_table_id=[]):
        """ Create and configure interfaces.

        :param ipv6: list of interface IPv6 capabilities
        :param ipv4: list of interface IPv4 capabilities
        :param ipv6_table_id: list of intf IPv6 FIB table_ids
        :param ipv4_table_id: list of intf IPv4 FIB table_ids
        :returns: List of created interfaces.
        """
        # how many interfaces?
        if len(ipv6):
            count = len(ipv6)
        else:
            count = len(ipv4)
        self.logger.debug("Creating and configuring %d interfaces" % (count))

        # fill up ipv6 and ipv4 lists if needed
        # not enabled (False) is the default
        if len(ipv6) < count:
            ipv6 += (count - len(ipv6)) * [False]
        if len(ipv4) < count:
            ipv4 += (count - len(ipv4)) * [False]

        # fill up table_id lists if needed
        # table_id 0 (global) is the default
        if len(ipv6_table_id) < count:
            ipv6_table_id += (count - len(ipv6_table_id)) * [0]
        if len(ipv4_table_id) < count:
            ipv4_table_id += (count - len(ipv4_table_id)) * [0]

        # create 'count' pg interfaces
        self.create_pg_interfaces(range(count))

        # setup all interfaces
        for i in range(count):
            intf = self.pg_interfaces[i]
            self.configure_interface(intf,
                                     ipv6[i], ipv4[i],
                                     ipv6_table_id[i], ipv4_table_id[i])

        if any(ipv6):
            self.logger.debug(self.vapi.cli("show ip6 neighbors"))
        if any(ipv4):
            self.logger.debug(self.vapi.cli("show ip arp"))
        self.logger.debug(self.vapi.cli("show interface"))
        self.logger.debug(self.vapi.cli("show hardware"))

        return self.pg_interfaces

    def teardown_interfaces(self):
        """ Unconfigure and bring down interface.
        """
        self.logger.debug("Tearing down interfaces")
        # tear down all interfaces
        # AFAIK they cannot be deleted
        for i in self.pg_interfaces:
            self.logger.debug("Tear down interface %s" % (i.name))
            i.admin_down()
            i.unconfig()

    def test_SRv6_T_Encaps(self):
        """ Test SRv6 Transit.Encaps behavior for IPv6.
        """
        # send traffic to one destination interface
        # source and destination are IPv6 only
        self.setup_interfaces(ipv6=[True, True])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure encaps IPv6 source address
        # needs to be done before SR Policy config
        # TODO: API?
        self.vapi.cli("set sr encaps source addr a3::")

        bsid = 'a3::9999:1'
        # configure SRv6 Policy
        # Note: segment list order: first -> last
        sr_policy = VppSRv6Policy(
            self, bsid=bsid,
            is_encap=1,
            sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
            weight=1, fib_table=0,
            segments=['a4::', 'a5::', 'a6::c7'],
            source='a3::')
        sr_policy.add_vpp_config()
        self.sr_policy = sr_policy

        # log the sr policies
        self.logger.info(self.vapi.cli("show sr policies"))

        # steer IPv6 traffic to a7::/64 into SRv6 Policy
        # use the bsid of the above self.sr_policy
        pol_steering = VppSRv6Steering(
                        self,
                        bsid=self.sr_policy.bsid,
                        prefix="a7::", mask_width=64,
                        traffic_type=SRv6PolicySteeringTypes.SR_STEER_IPV6,
                        sr_policy_index=0, table_id=0,
                        sw_if_index=0)
        pol_steering.add_vpp_config()

        # log the sr steering policies
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # create packets
        count = len(self.pg_packet_sizes)
        dst_inner = 'a7::1234'
        pkts = []

        # create IPv6 packets without SRH
        packet_header = self.create_packet_header_IPv6(dst_inner)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # create IPv6 packets with SRH
        # packets with segments-left 1, active segment a7::
        packet_header = self.create_packet_header_IPv6_SRH(
            sidlist=['a8::', 'a7::', 'a6::'],
            segleft=1)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # create IPv6 packets with SRH and IPv6
        # packets with segments-left 1, active segment a7::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
            dst_inner,
            sidlist=['a8::', 'a7::', 'a6::'],
            segleft=1)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_T_Encaps)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SR steering
        pol_steering.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # remove SR Policies
        self.sr_policy.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr policies"))

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_T_Insert(self):
        """ Test SRv6 Transit.Insert behavior (IPv6 only).
        """
        # send traffic to one destination interface
        # source and destination are IPv6 only
        self.setup_interfaces(ipv6=[True, True])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure encaps IPv6 source address
        # needs to be done before SR Policy config
        # TODO: API?
        self.vapi.cli("set sr encaps source addr a3::")

        bsid = 'a3::9999:1'
        # configure SRv6 Policy
        # Note: segment list order: first -> last
        sr_policy = VppSRv6Policy(
            self, bsid=bsid,
            is_encap=0,
            sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
            weight=1, fib_table=0,
            segments=['a4::', 'a5::', 'a6::c7'],
            source='a3::')
        sr_policy.add_vpp_config()
        self.sr_policy = sr_policy

        # log the sr policies
        self.logger.info(self.vapi.cli("show sr policies"))

        # steer IPv6 traffic to a7::/64 into SRv6 Policy
        # use the bsid of the above self.sr_policy
        pol_steering = VppSRv6Steering(
                        self,
                        bsid=self.sr_policy.bsid,
                        prefix="a7::", mask_width=64,
                        traffic_type=SRv6PolicySteeringTypes.SR_STEER_IPV6,
                        sr_policy_index=0, table_id=0,
                        sw_if_index=0)
        pol_steering.add_vpp_config()

        # log the sr steering policies
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # create packets
        count = len(self.pg_packet_sizes)
        dst_inner = 'a7::1234'
        pkts = []

        # create IPv6 packets without SRH
        packet_header = self.create_packet_header_IPv6(dst_inner)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # create IPv6 packets with SRH
        # packets with segments-left 1, active segment a7::
        packet_header = self.create_packet_header_IPv6_SRH(
            sidlist=['a8::', 'a7::', 'a6::'],
            segleft=1)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_T_Insert)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SR steering
        pol_steering.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # remove SR Policies
        self.sr_policy.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr policies"))

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_T_Encaps_IPv4(self):
        """ Test SRv6 Transit.Encaps behavior for IPv4.
        """
        # send traffic to one destination interface
        # source interface is IPv4 only
        # destination interface is IPv6 only
        self.setup_interfaces(ipv6=[False, True], ipv4=[True, False])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure encaps IPv6 source address
        # needs to be done before SR Policy config
        # TODO: API?
        self.vapi.cli("set sr encaps source addr a3::")

        bsid = 'a3::9999:1'
        # configure SRv6 Policy
        # Note: segment list order: first -> last
        sr_policy = VppSRv6Policy(
            self, bsid=bsid,
            is_encap=1,
            sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
            weight=1, fib_table=0,
            segments=['a4::', 'a5::', 'a6::c7'],
            source='a3::')
        sr_policy.add_vpp_config()
        self.sr_policy = sr_policy

        # log the sr policies
        self.logger.info(self.vapi.cli("show sr policies"))

        # steer IPv4 traffic to 7.1.1.0/24 into SRv6 Policy
        # use the bsid of the above self.sr_policy
        pol_steering = VppSRv6Steering(
                        self,
                        bsid=self.sr_policy.bsid,
                        prefix="7.1.1.0", mask_width=24,
                        traffic_type=SRv6PolicySteeringTypes.SR_STEER_IPV4,
                        sr_policy_index=0, table_id=0,
                        sw_if_index=0)
        pol_steering.add_vpp_config()

        # log the sr steering policies
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # create packets
        count = len(self.pg_packet_sizes)
        dst_inner = '7.1.1.123'
        pkts = []

        # create IPv4 packets
        packet_header = self.create_packet_header_IPv4(dst_inner)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_T_Encaps_IPv4)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SR steering
        pol_steering.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # remove SR Policies
        self.sr_policy.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr policies"))

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    @unittest.skip("VPP crashes after running this test")
    def test_SRv6_T_Encaps_L2(self):
        """ Test SRv6 Transit.Encaps behavior for L2.
        """
        # send traffic to one destination interface
        # source interface is IPv4 only TODO?
        # destination interface is IPv6 only
        self.setup_interfaces(ipv6=[False, True], ipv4=[False, False])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure encaps IPv6 source address
        # needs to be done before SR Policy config
        # TODO: API?
        self.vapi.cli("set sr encaps source addr a3::")

        bsid = 'a3::9999:1'
        # configure SRv6 Policy
        # Note: segment list order: first -> last
        sr_policy = VppSRv6Policy(
            self, bsid=bsid,
            is_encap=1,
            sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
            weight=1, fib_table=0,
            segments=['a4::', 'a5::', 'a6::c7'],
            source='a3::')
        sr_policy.add_vpp_config()
        self.sr_policy = sr_policy

        # log the sr policies
        self.logger.info(self.vapi.cli("show sr policies"))

        # steer L2 traffic into SRv6 Policy
        # use the bsid of the above self.sr_policy
        pol_steering = VppSRv6Steering(
                        self,
                        bsid=self.sr_policy.bsid,
                        prefix="::", mask_width=0,
                        traffic_type=SRv6PolicySteeringTypes.SR_STEER_L2,
                        sr_policy_index=0, table_id=0,
                        sw_if_index=self.pg0.sw_if_index)
        pol_steering.add_vpp_config()

        # log the sr steering policies
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # create packets
        count = len(self.pg_packet_sizes)
        pkts = []

        # create L2 packets without dot1q header
        packet_header = self.create_packet_header_L2()
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # create L2 packets with dot1q header
        packet_header = self.create_packet_header_L2(vlan=123)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_T_Encaps_L2)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SR steering
        pol_steering.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # remove SR Policies
        self.sr_policy.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr policies"))

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End(self):
        """ Test SRv6 End (without PSP) behavior.
        """
        # send traffic to one destination interface
        # source and destination interfaces are IPv6 only
        self.setup_interfaces(ipv6=[True, True])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure SRv6 localSID End without PSP behavior
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='A3::0',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_END,
                        nh_addr='::',
                        end_psp=0,
                        sw_if_index=0,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=2, SL=1, SL=0)
        # send one packet per SL value per packet size
        # SL=0 packet with localSID End with USP needs 2nd SRH
        count = len(self.pg_packet_sizes)
        dst_inner = 'a4::1234'
        pkts = []

        # packets with segments-left 2, active segment a3::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                dst_inner,
                sidlist=['a5::', 'a4::', 'a3::'],
                segleft=2)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets with segments-left 1, active segment a3::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                dst_inner,
                sidlist=['a4::', 'a3::', 'a2::'],
                segleft=1)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # TODO: test behavior with SL=0 packet (needs 2*SRH?)

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_with_PSP(self):
        """ Test SRv6 End with PSP behavior.
        """
        # send traffic to one destination interface
        # source and destination interfaces are IPv6 only
        self.setup_interfaces(ipv6=[True, True])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure SRv6 localSID End with PSP behavior
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='A3::0',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_END,
                        nh_addr='::',
                        end_psp=1,
                        sw_if_index=0,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=2, SL=1)
        # send one packet per SL value per packet size
        # SL=0 packet with localSID End with PSP is dropped
        count = len(self.pg_packet_sizes)
        dst_inner = 'a4::1234'
        pkts = []

        # packets with segments-left 2, active segment a3::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                    dst_inner,
                    sidlist=['a5::', 'a4::', 'a3::'],
                    segleft=2)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets with segments-left 1, active segment a3::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                    dst_inner,
                    sidlist=['a4::', 'a3::', 'a2::'],
                    segleft=1)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End_PSP)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_X(self):
        """ Test SRv6 End.X (without PSP) behavior.
        """
        # create three interfaces (1 source, 2 destinations)
        # source and destination interfaces are IPv6 only
        self.setup_interfaces(ipv6=[True, True, True])

        # configure FIB entries
        # a4::/64 via pg1 and pg2
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6),
                            VppRoutePath(self.pg2.remote_ip6,
                                         self.pg2.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()
        self.logger.debug(self.vapi.cli("show ip6 fib"))

        # configure SRv6 localSID End.X without PSP behavior
        # End.X points to interface pg1
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='A3::C4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_X,
                        nh_addr=self.pg1.remote_ip6,
                        end_psp=0,
                        sw_if_index=self.pg1.sw_if_index,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=2, SL=1)
        # send one packet per SL value per packet size
        # SL=0 packet with localSID End with PSP is dropped
        count = len(self.pg_packet_sizes)
        dst_inner = 'a4::1234'
        pkts = []

        # packets with segments-left 2, active segment a3::c4
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                    dst_inner,
                    sidlist=['a5::', 'a4::', 'a3::c4'],
                    segleft=2)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets with segments-left 1, active segment a3::c4
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                    dst_inner,
                    sidlist=['a4::', 'a3::c4', 'a2::'],
                    segleft=1)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        # using same comparison function as End (no PSP)
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End)

        # assert nothing was received on the other interface (pg2)
        self.pg2.assert_nothing_captured("mis-directed packet(s)")

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_X_with_PSP(self):
        """ Test SRv6 End.X with PSP behavior.
        """
        # create three interfaces (1 source, 2 destinations)
        # source and destination interfaces are IPv6 only
        self.setup_interfaces(ipv6=[True, True, True])

        # configure FIB entries
        # a4::/64 via pg1 and pg2
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6),
                            VppRoutePath(self.pg2.remote_ip6,
                                         self.pg2.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure SRv6 localSID End with PSP behavior
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='A3::C4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_X,
                        nh_addr=self.pg1.remote_ip6,
                        end_psp=1,
                        sw_if_index=self.pg1.sw_if_index,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=2, SL=1)
        # send one packet per SL value per packet size
        # SL=0 packet with localSID End with PSP is dropped
        count = len(self.pg_packet_sizes)
        dst_inner = 'a4::1234'
        pkts = []

        # packets with segments-left 2, active segment a3::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                    dst_inner,
                    sidlist=['a5::', 'a4::', 'a3::c4'],
                    segleft=2)
        # create traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets with segments-left 1, active segment a3::
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                    dst_inner,
                    sidlist=['a4::', 'a3::c4', 'a2::'],
                    segleft=1)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        # using same comparison function as End with PSP
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End_PSP)

        # assert nothing was received on the other interface (pg2)
        self.pg2.assert_nothing_captured("mis-directed packet(s)")

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_DX6(self):
        """ Test SRv6 End.DX6 behavior.
        """
        # send traffic to one destination interface
        # source and destination interfaces are IPv6 only
        self.setup_interfaces(ipv6=[True, True])

        # configure SRv6 localSID End.DX6 behavior
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='a3::c4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX6,
                        nh_addr=self.pg1.remote_ip6,
                        end_psp=0,
                        sw_if_index=self.pg1.sw_if_index,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=0)
        # send one packet per packet size
        count = len(self.pg_packet_sizes)
        dst_inner = 'a4::1234'  # inner header destination address
        pkts = []

        # packets with SRH, segments-left 0, active segment a3::c4
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                        dst_inner,
                        sidlist=['a3::c4', 'a2::', 'a1::'],
                        segleft=0)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets without SRH, IPv6 in IPv6
        # outer IPv6 dest addr is the localsid End.DX6
        packet_header = self.create_packet_header_IPv6_IPv6(
                                            dst_inner,
                                            dst_outer='a3::c4')
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End_DX6)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_DT6(self):
        """ Test SRv6 End.DT6 behavior.
        """
        # create three interfaces (1 source, 2 destinations)
        # all interfaces are IPv6 only
        # source interface in global FIB (0)
        # destination interfaces in global and vrf
        vrf_1 = 1
        self.setup_interfaces(ipv6=[True, True, True],
                              ipv6_table_id=[0, 0, vrf_1])

        # configure FIB entries
        # a4::/64 is reachable
        #     via pg1 in table 0 (global)
        #     and via pg2 in table vrf_1
        route0 = VppIpRoute(self, "a4::", 64,
                            [VppRoutePath(self.pg1.remote_ip6,
                                          self.pg1.sw_if_index,
                                          proto=DpoProto.DPO_PROTO_IP6,
                                          nh_table_id=0)],
                            table_id=0,
                            is_ip6=1)
        route0.add_vpp_config()
        route1 = VppIpRoute(self, "a4::", 64,
                            [VppRoutePath(self.pg2.remote_ip6,
                                          self.pg2.sw_if_index,
                                          proto=DpoProto.DPO_PROTO_IP6,
                                          nh_table_id=vrf_1)],
                            table_id=vrf_1,
                            is_ip6=1)
        route1.add_vpp_config()
        self.logger.debug(self.vapi.cli("show ip6 fib"))

        # configure SRv6 localSID End.DT6 behavior
        # Note:
        # fib_table: where the localsid is installed
        # sw_if_index: in T-variants of localsid this is the vrf table_id
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='a3::c4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DT6,
                        nh_addr='::',
                        end_psp=0,
                        sw_if_index=vrf_1,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=0)
        # send one packet per packet size
        count = len(self.pg_packet_sizes)
        dst_inner = 'a4::1234'  # inner header destination address
        pkts = []

        # packets with SRH, segments-left 0, active segment a3::c4
        packet_header = self.create_packet_header_IPv6_SRH_IPv6(
                        dst_inner,
                        sidlist=['a3::c4', 'a2::', 'a1::'],
                        segleft=0)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg2, packet_header,
                                       self.pg_packet_sizes, count))

        # packets without SRH, IPv6 in IPv6
        # outer IPv6 dest addr is the localsid End.DT6
        packet_header = self.create_packet_header_IPv6_IPv6(
                                            dst_inner,
                                            dst_outer='a3::c4')
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg2, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        # using same comparison function as End.DX6
        self.send_and_verify_pkts(self.pg0, pkts, self.pg2,
                                  self.compare_rx_tx_packet_End_DX6)

        # assert nothing was received on the other interface (pg2)
        self.pg1.assert_nothing_captured("mis-directed packet(s)")

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_DX4(self):
        """ Test SRv6 End.DX4 behavior.
        """
        # send traffic to one destination interface
        # source interface is IPv6 only
        # destination interface is IPv4 only
        self.setup_interfaces(ipv6=[True, False], ipv4=[False, True])

        # configure SRv6 localSID End.DX4 behavior
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='a3::c4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX4,
                        nh_addr=self.pg1.remote_ip4,
                        end_psp=0,
                        sw_if_index=self.pg1.sw_if_index,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # send one packet per packet size
        count = len(self.pg_packet_sizes)
        dst_inner = '4.1.1.123'  # inner header destination address
        pkts = []

        # packets with SRH, segments-left 0, active segment a3::c4
        packet_header = self.create_packet_header_IPv6_SRH_IPv4(
                        dst_inner,
                        sidlist=['a3::c4', 'a2::', 'a1::'],
                        segleft=0)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets without SRH, IPv4 in IPv6
        # outer IPv6 dest addr is the localsid End.DX4
        packet_header = self.create_packet_header_IPv6_IPv4(
                                            dst_inner,
                                            dst_outer='a3::c4')
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End_DX4)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_DT4(self):
        """ Test SRv6 End.DT4 behavior.
        """
        # create three interfaces (1 source, 2 destinations)
        # source interface is IPv6-only
        # destination interfaces are IPv4 only
        # source interface in global FIB (0)
        # destination interfaces in global and vrf
        vrf_1 = 1
        self.setup_interfaces(ipv6=[True, False, False],
                              ipv4=[False, True, True],
                              ipv6_table_id=[0, 0, 0],
                              ipv4_table_id=[0, 0, vrf_1])

        # configure FIB entries
        # 4.1.1.0/24 is reachable
        #     via pg1 in table 0 (global)
        #     and via pg2 in table vrf_1
        route0 = VppIpRoute(self, "4.1.1.0", 24,
                            [VppRoutePath(self.pg1.remote_ip4,
                                          self.pg1.sw_if_index,
                                          nh_table_id=0)],
                            table_id=0,
                            is_ip6=0)
        route0.add_vpp_config()
        route1 = VppIpRoute(self, "4.1.1.0", 24,
                            [VppRoutePath(self.pg2.remote_ip4,
                                          self.pg2.sw_if_index,
                                          nh_table_id=vrf_1)],
                            table_id=vrf_1,
                            is_ip6=0)
        route1.add_vpp_config()
        self.logger.debug(self.vapi.cli("show ip fib"))

        # configure SRv6 localSID End.DT6 behavior
        # Note:
        # fib_table: where the localsid is installed
        # sw_if_index: in T-variants of localsid: vrf table_id
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='a3::c4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DT4,
                        nh_addr='::',
                        end_psp=0,
                        sw_if_index=vrf_1,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # create IPv6 packets with SRH (SL=0)
        # send one packet per packet size
        count = len(self.pg_packet_sizes)
        dst_inner = '4.1.1.123'  # inner header destination address
        pkts = []

        # packets with SRH, segments-left 0, active segment a3::c4
        packet_header = self.create_packet_header_IPv6_SRH_IPv4(
                        dst_inner,
                        sidlist=['a3::c4', 'a2::', 'a1::'],
                        segleft=0)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg2, packet_header,
                                       self.pg_packet_sizes, count))

        # packets without SRH, IPv6 in IPv6
        # outer IPv6 dest addr is the localsid End.DX4
        packet_header = self.create_packet_header_IPv6_IPv4(
                                            dst_inner,
                                            dst_outer='a3::c4')
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg2, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        # using same comparison function as End.DX4
        self.send_and_verify_pkts(self.pg0, pkts, self.pg2,
                                  self.compare_rx_tx_packet_End_DX4)

        # assert nothing was received on the other interface (pg2)
        self.pg1.assert_nothing_captured("mis-directed packet(s)")

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_End_DX2(self):
        """ Test SRv6 End.DX2 behavior.
        """
        # send traffic to one destination interface
        # source interface is IPv6 only
        self.setup_interfaces(ipv6=[True, False], ipv4=[False, False])

        # configure SRv6 localSID End.DX2 behavior
        localsid = VppSRv6LocalSID(
                        self, localsid_addr='a3::c4',
                        behavior=SRv6LocalSIDBehaviors.SR_BEHAVIOR_DX2,
                        nh_addr='::',
                        end_psp=0,
                        sw_if_index=self.pg1.sw_if_index,
                        vlan_index=0,
                        fib_table=0)
        localsid.add_vpp_config()
        # log the localsids
        self.logger.debug(self.vapi.cli("show sr localsid"))

        # send one packet per packet size
        count = len(self.pg_packet_sizes)
        pkts = []

        # packets with SRH, segments-left 0, active segment a3::c4
        # L2 has no dot1q header
        packet_header = self.create_packet_header_IPv6_SRH_L2(
                            sidlist=['a3::c4', 'a2::', 'a1::'],
                            segleft=0,
                            vlan=0)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets with SRH, segments-left 0, active segment a3::c4
        # L2 has dot1q header
        packet_header = self.create_packet_header_IPv6_SRH_L2(
                            sidlist=['a3::c4', 'a2::', 'a1::'],
                            segleft=0,
                            vlan=123)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets without SRH, L2 in IPv6
        # outer IPv6 dest addr is the localsid End.DX2
        # L2 has no dot1q header
        packet_header = self.create_packet_header_IPv6_L2(
                                            dst_outer='a3::c4',
                                            vlan=0)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # packets without SRH, L2 in IPv6
        # outer IPv6 dest addr is the localsid End.DX2
        # L2 has dot1q header
        packet_header = self.create_packet_header_IPv6_L2(
                                            dst_outer='a3::c4',
                                            vlan=123)
        # add to traffic stream pg0->pg1
        pkts.extend(self.create_stream(self.pg0, self.pg1, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg0, pkts, self.pg1,
                                  self.compare_rx_tx_packet_End_DX2)

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove SRv6 localSIDs
        localsid.remove_vpp_config()

        # cleanup interfaces
        self.teardown_interfaces()

    def test_SRv6_T_Insert_Classifier(self):
        """ Test SRv6 Transit.Insert behavior (IPv6 only).
            steer packets using the classifier
        """
        # send traffic to one destination interface
        # source and destination are IPv6 only
        self.setup_interfaces(ipv6=[False, False, False, True, True])

        # configure FIB entries
        route = VppIpRoute(self, "a4::", 64,
                           [VppRoutePath(self.pg4.remote_ip6,
                                         self.pg4.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        # configure encaps IPv6 source address
        # needs to be done before SR Policy config
        # TODO: API?
        self.vapi.cli("set sr encaps source addr a3::")

        bsid = 'a3::9999:1'
        # configure SRv6 Policy
        # Note: segment list order: first -> last
        sr_policy = VppSRv6Policy(
            self, bsid=bsid,
            is_encap=0,
            sr_type=SRv6PolicyType.SR_POLICY_TYPE_DEFAULT,
            weight=1, fib_table=0,
            segments=['a4::', 'a5::', 'a6::c7'],
            source='a3::')
        sr_policy.add_vpp_config()
        self.sr_policy = sr_policy

        # log the sr policies
        self.logger.info(self.vapi.cli("show sr policies"))

        # add classify table
        # mask on dst ip address prefix a7::/8
        mask = '{:0<16}'.format('ff')
        r = self.vapi.classify_add_del_table(
            1,
            binascii.unhexlify(mask),
            match_n_vectors=(len(mask) - 1) // 32 + 1,
            current_data_flag=1,
            skip_n_vectors=2)  # data offset
        self.assertIsNotNone(r, msg='No response msg for add_del_table')
        table_index = r.new_table_index

        # add the source routign node as a ip6 inacl netxt node
        r = self.vapi.add_node_next('ip6-inacl',
                                    'sr-pl-rewrite-insert')
        inacl_next_node_index = r.node_index

        match = '{:0<16}'.format('a7')
        r = self.vapi.classify_add_del_session(
            1,
            table_index,
            binascii.unhexlify(match),
            hit_next_index=inacl_next_node_index,
            action=3,
            metadata=0)  # sr policy index
        self.assertIsNotNone(r, msg='No response msg for add_del_session')

        # log the classify table used in the steering policy
        self.logger.info(self.vapi.cli("show classify table"))

        r = self.vapi.input_acl_set_interface(
            is_add=1,
            sw_if_index=self.pg3.sw_if_index,
            ip6_table_index=table_index)
        self.assertIsNotNone(r,
                             msg='No response msg for input_acl_set_interface')

        # log the ip6 inacl
        self.logger.info(self.vapi.cli("show inacl type ip6"))

        # create packets
        count = len(self.pg_packet_sizes)
        dst_inner = 'a7::1234'
        pkts = []

        # create IPv6 packets without SRH
        packet_header = self.create_packet_header_IPv6(dst_inner)
        # create traffic stream pg3->pg4
        pkts.extend(self.create_stream(self.pg3, self.pg4, packet_header,
                                       self.pg_packet_sizes, count))

        # create IPv6 packets with SRH
        # packets with segments-left 1, active segment a7::
        packet_header = self.create_packet_header_IPv6_SRH(
            sidlist=['a8::', 'a7::', 'a6::'],
            segleft=1)
        # create traffic stream pg3->pg4
        pkts.extend(self.create_stream(self.pg3, self.pg4, packet_header,
                                       self.pg_packet_sizes, count))

        # send packets and verify received packets
        self.send_and_verify_pkts(self.pg3, pkts, self.pg4,
                                  self.compare_rx_tx_packet_T_Insert)

        # remove the interface l2 input feature
        r = self.vapi.input_acl_set_interface(
            is_add=0,
            sw_if_index=self.pg3.sw_if_index,
            ip6_table_index=table_index)
        self.assertIsNotNone(r,
                             msg='No response msg for input_acl_set_interface')

        # log the ip6 inacl after cleaning
        self.logger.info(self.vapi.cli("show inacl type ip6"))

        # log the localsid counters
        self.logger.info(self.vapi.cli("show sr localsid"))

        # remove classifier SR steering
        # classifier_steering.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr steering policies"))

        # remove SR Policies
        self.sr_policy.remove_vpp_config()
        self.logger.info(self.vapi.cli("show sr policies"))

        # remove classify session and table
        r = self.vapi.classify_add_del_session(
            0,
            table_index,
            binascii.unhexlify(match))
        self.assertIsNotNone(r, msg='No response msg for add_del_session')

        r = self.vapi.classify_add_del_table(
            0,
            binascii.unhexlify(mask),
            table_index=table_index)
        self.assertIsNotNone(r, msg='No response msg for add_del_table')

        self.logger.info(self.vapi.cli("show classify table"))

        # remove FIB entries
        # done by tearDown

        # cleanup interfaces
        self.teardown_interfaces()

    def compare_rx_tx_packet_T_Encaps(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing T.Encaps

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # T.Encaps updates the headers as follows:
        # SR Policy seglist (S3, S2, S1)
        # SR Policy source C
        # IPv6:
        # in: IPv6(A, B2)
        # out: IPv6(C, S1)SRH(S3, S2, S1; SL=2)IPv6(A, B2)
        # IPv6 + SRH:
        # in: IPv6(A, B2)SRH(B3, B2, B1; SL=1)
        # out: IPv6(C, S1)SRH(S3, S2, S1; SL=2)IPv6(a, B2)SRH(B3, B2, B1; SL=1)

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)
        rx_srh = None

        tx_ip = tx_pkt.getlayer(IPv6)

        # expected segment-list
        seglist = self.sr_policy.segments
        # reverse list to get order as in SRH
        tx_seglist = seglist[::-1]

        # get source address of SR Policy
        sr_policy_source = self.sr_policy.source

        # rx'ed packet should have SRH
        self.assertTrue(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
        # get SRH
        rx_srh = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting)

        # received ip.src should be equal to SR Policy source
        self.assertEqual(rx_ip.src, sr_policy_source)
        # received ip.dst should be equal to expected sidlist[lastentry]
        self.assertEqual(rx_ip.dst, tx_seglist[-1])
        # rx'ed seglist should be equal to expected seglist
        self.assertEqual(rx_srh.addresses, tx_seglist)
        # segleft should be equal to size expected seglist-1
        self.assertEqual(rx_srh.segleft, len(tx_seglist)-1)
        # segleft should be equal to lastentry
        self.assertEqual(rx_srh.segleft, rx_srh.lastentry)

        # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt
        # except for the hop-limit field
        #   -> update tx'ed hlim to the expected hlim
        tx_ip.hlim = tx_ip.hlim - 1

        self.assertEqual(rx_srh.payload, tx_ip)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_T_Encaps_IPv4(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing T.Encaps for IPv4

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # T.Encaps for IPv4 updates the headers as follows:
        # SR Policy seglist (S3, S2, S1)
        # SR Policy source C
        # IPv4:
        # in: IPv4(A, B2)
        # out: IPv6(C, S1)SRH(S3, S2, S1; SL=2)IPv4(A, B2)

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)
        rx_srh = None

        tx_ip = tx_pkt.getlayer(IP)

        # expected segment-list
        seglist = self.sr_policy.segments
        # reverse list to get order as in SRH
        tx_seglist = seglist[::-1]

        # get source address of SR Policy
        sr_policy_source = self.sr_policy.source

        # checks common to cases tx with and without SRH
        # rx'ed packet should have SRH and IPv4 header
        self.assertTrue(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
        self.assertTrue(rx_ip.payload.haslayer(IP))
        # get SRH
        rx_srh = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting)

        # received ip.src should be equal to SR Policy source
        self.assertEqual(rx_ip.src, sr_policy_source)
        # received ip.dst should be equal to sidlist[lastentry]
        self.assertEqual(rx_ip.dst, tx_seglist[-1])
        # rx'ed seglist should be equal to seglist
        self.assertEqual(rx_srh.addresses, tx_seglist)
        # segleft should be equal to size seglist-1
        self.assertEqual(rx_srh.segleft, len(tx_seglist)-1)
        # segleft should be equal to lastentry
        self.assertEqual(rx_srh.segleft, rx_srh.lastentry)

        # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt
        # except for the ttl field and ip checksum
        #   -> adjust tx'ed ttl to expected ttl
        tx_ip.ttl = tx_ip.ttl - 1
        #   -> set tx'ed ip checksum to None and let scapy recompute
        tx_ip.chksum = None
        # read back the pkt (with str()) to force computing these fields
        # probably other ways to accomplish this are possible
        tx_ip = IP(str(tx_ip))

        self.assertEqual(rx_srh.payload, tx_ip)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_T_Encaps_L2(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing T.Encaps for L2

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # T.Encaps for L2 updates the headers as follows:
        # SR Policy seglist (S3, S2, S1)
        # SR Policy source C
        # L2:
        # in: L2
        # out: IPv6(C, S1)SRH(S3, S2, S1; SL=2)L2

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)
        rx_srh = None

        tx_ether = tx_pkt.getlayer(Ether)

        # expected segment-list
        seglist = self.sr_policy.segments
        # reverse list to get order as in SRH
        tx_seglist = seglist[::-1]

        # get source address of SR Policy
        sr_policy_source = self.sr_policy.source

        # rx'ed packet should have SRH
        self.assertTrue(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
        # get SRH
        rx_srh = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting)

        # received ip.src should be equal to SR Policy source
        self.assertEqual(rx_ip.src, sr_policy_source)
        # received ip.dst should be equal to sidlist[lastentry]
        self.assertEqual(rx_ip.dst, tx_seglist[-1])
        # rx'ed seglist should be equal to seglist
        self.assertEqual(rx_srh.addresses, tx_seglist)
        # segleft should be equal to size seglist-1
        self.assertEqual(rx_srh.segleft, len(tx_seglist)-1)
        # segleft should be equal to lastentry
        self.assertEqual(rx_srh.segleft, rx_srh.lastentry)
        # nh should be "No Next Header" (59)
        self.assertEqual(rx_srh.nh, 59)

        # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt
        self.assertEqual(Ether(str(rx_srh.payload)), tx_ether)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_T_Insert(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing T.Insert

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # T.Insert updates the headers as follows:
        # IPv6:
        # in: IPv6(A, B2)
        # out: IPv6(A, S1)SRH(B2, S3, S2, S1; SL=3)
        # IPv6 + SRH:
        # in: IPv6(A, B2)SRH(B3, B2, B1; SL=1)
        # out: IPv6(A, S1)SRH(B2, S3, S2, S1; SL=3)SRH(B3, B2, B1; SL=1)

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)
        rx_srh = None
        rx_ip2 = None
        rx_srh2 = None
        rx_ip3 = None
        rx_udp = rx_pkt[UDP]

        tx_ip = tx_pkt.getlayer(IPv6)
        tx_srh = None
        tx_ip2 = None
        # some packets have been tx'ed with an SRH, some without it
        # get SRH if tx'ed packet has it
        if tx_pkt.haslayer(IPv6ExtHdrSegmentRouting):
            tx_srh = tx_pkt.getlayer(IPv6ExtHdrSegmentRouting)
            tx_ip2 = tx_pkt.getlayer(IPv6, 2)
        tx_udp = tx_pkt[UDP]

        # expected segment-list (make copy of SR Policy segment list)
        seglist = self.sr_policy.segments[:]
        # expected seglist has initial dest addr as last segment
        seglist.append(tx_ip.dst)
        # reverse list to get order as in SRH
        tx_seglist = seglist[::-1]

        # get source address of SR Policy
        sr_policy_source = self.sr_policy.source

        # checks common to cases tx with and without SRH
        # rx'ed packet should have SRH and only one IPv6 header
        self.assertTrue(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
        self.assertFalse(rx_ip.payload.haslayer(IPv6))
        # get SRH
        rx_srh = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting)

        # rx'ed ip.src should be equal to tx'ed ip.src
        self.assertEqual(rx_ip.src, tx_ip.src)
        # rx'ed ip.dst should be equal to sidlist[lastentry]
        self.assertEqual(rx_ip.dst, tx_seglist[-1])

        # rx'ed seglist should be equal to expected seglist
        self.assertEqual(rx_srh.addresses, tx_seglist)
        # segleft should be equal to size(expected seglist)-1
        self.assertEqual(rx_srh.segleft, len(tx_seglist)-1)
        # segleft should be equal to lastentry
        self.assertEqual(rx_srh.segleft, rx_srh.lastentry)

        if tx_srh:  # packet was tx'ed with SRH
            # packet should have 2nd SRH
            self.assertTrue(rx_srh.payload.haslayer(IPv6ExtHdrSegmentRouting))
            # get 2nd SRH
            rx_srh2 = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting, 2)

            # rx'ed srh2.addresses should be equal to tx'ed srh.addresses
            self.assertEqual(rx_srh2.addresses, tx_srh.addresses)
            # rx'ed srh2.segleft should be equal to tx'ed srh.segleft
            self.assertEqual(rx_srh2.segleft, tx_srh.segleft)
            # rx'ed srh2.lastentry should be equal to tx'ed srh.lastentry
            self.assertEqual(rx_srh2.lastentry, tx_srh.lastentry)

        else:  # packet was tx'ed without SRH
            # rx packet should have no other SRH
            self.assertFalse(rx_srh.payload.haslayer(IPv6ExtHdrSegmentRouting))

        # UDP layer should be unchanged
        self.assertEqual(rx_udp, tx_udp)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_End(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing End (without PSP)

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # End (no PSP) updates the headers as follows:
        # IPv6 + SRH:
        # in: IPv6(A, S1)SRH(S3, S2, S1; SL=2)
        # out: IPv6(A, S2)SRH(S3, S2, S1; SL=1)

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)
        rx_srh = None
        rx_ip2 = None
        rx_udp = rx_pkt[UDP]

        tx_ip = tx_pkt.getlayer(IPv6)
        # we know the packet has been tx'ed
        # with an inner IPv6 header and an SRH
        tx_ip2 = tx_pkt.getlayer(IPv6, 2)
        tx_srh = tx_pkt.getlayer(IPv6ExtHdrSegmentRouting)
        tx_udp = tx_pkt[UDP]

        # common checks, regardless of tx segleft value
        # rx'ed packet should have 2nd IPv6 header
        self.assertTrue(rx_ip.payload.haslayer(IPv6))
        # get second (inner) IPv6 header
        rx_ip2 = rx_pkt.getlayer(IPv6, 2)

        if tx_ip.segleft > 0:
            # SRH should NOT have been popped:
            #   End SID without PSP does not pop SRH if segleft>0
            self.assertTrue(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
            rx_srh = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting)

            # received ip.src should be equal to expected ip.src
            self.assertEqual(rx_ip.src, tx_ip.src)
            # sidlist should be unchanged
            self.assertEqual(rx_srh.addresses, tx_srh.addresses)
            # segleft should have been decremented
            self.assertEqual(rx_srh.segleft, tx_srh.segleft-1)
            # received ip.dst should be equal to sidlist[segleft]
            self.assertEqual(rx_ip.dst, rx_srh.addresses[rx_srh.segleft])
            # lastentry should be unchanged
            self.assertEqual(rx_srh.lastentry, tx_srh.lastentry)
            # inner IPv6 packet (ip2) should be unchanged
            self.assertEqual(rx_ip2.src, tx_ip2.src)
            self.assertEqual(rx_ip2.dst, tx_ip2.dst)
        # else:  # tx_ip.segleft == 0
            # TODO: Does this work with 2 SRHs in ingress packet?

        # UDP layer should be unchanged
        self.assertEqual(rx_udp, tx_udp)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_End_PSP(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing End with PSP

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # End (PSP) updates the headers as follows:
        # IPv6 + SRH (SL>1):
        # in: IPv6(A, S1)SRH(S3, S2, S1; SL=2)
        # out: IPv6(A, S2)SRH(S3, S2, S1; SL=1)
        # IPv6 + SRH (SL=1):
        # in: IPv6(A, S2)SRH(S3, S2, S1; SL=1)
        # out: IPv6(A, S3)

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)
        rx_srh = None
        rx_ip2 = None
        rx_udp = rx_pkt[UDP]

        tx_ip = tx_pkt.getlayer(IPv6)
        # we know the packet has been tx'ed
        # with an inner IPv6 header and an SRH
        tx_ip2 = tx_pkt.getlayer(IPv6, 2)
        tx_srh = tx_pkt.getlayer(IPv6ExtHdrSegmentRouting)
        tx_udp = tx_pkt[UDP]

        # common checks, regardless of tx segleft value
        self.assertTrue(rx_ip.payload.haslayer(IPv6))
        rx_ip2 = rx_pkt.getlayer(IPv6, 2)
        # inner IPv6 packet (ip2) should be unchanged
        self.assertEqual(rx_ip2.src, tx_ip2.src)
        self.assertEqual(rx_ip2.dst, tx_ip2.dst)

        if tx_ip.segleft > 1:
            # SRH should NOT have been popped:
            #   End SID with PSP does not pop SRH if segleft>1
            # rx'ed packet should have SRH
            self.assertTrue(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
            rx_srh = rx_pkt.getlayer(IPv6ExtHdrSegmentRouting)

            # received ip.src should be equal to expected ip.src
            self.assertEqual(rx_ip.src, tx_ip.src)
            # sidlist should be unchanged
            self.assertEqual(rx_srh.addresses, tx_srh.addresses)
            # segleft should have been decremented
            self.assertEqual(rx_srh.segleft, tx_srh.segleft-1)
            # received ip.dst should be equal to sidlist[segleft]
            self.assertEqual(rx_ip.dst, rx_srh.addresses[rx_srh.segleft])
            # lastentry should be unchanged
            self.assertEqual(rx_srh.lastentry, tx_srh.lastentry)

        else:  # tx_ip.segleft <= 1
            # SRH should have been popped:
            #   End SID with PSP and segleft=1 pops SRH
            # the two IPv6 headers are still present
            # outer IPv6 header has DA == last segment of popped SRH
            # SRH should not be present
            self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))
            # outer IPv6 header ip.src should be equal to tx'ed ip.src
            self.assertEqual(rx_ip.src, tx_ip.src)
            # outer IPv6 header ip.dst should be = to tx'ed sidlist[segleft-1]
            self.assertEqual(rx_ip.dst, tx_srh.addresses[tx_srh.segleft-1])

        # UDP layer should be unchanged
        self.assertEqual(rx_udp, tx_udp)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_End_DX6(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing End.DX6

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # End.DX6 updates the headers as follows:
        # IPv6 + SRH (SL=0):
        # in: IPv6(A, S3)SRH(S3, S2, S1; SL=0)IPv6(B, D)
        # out: IPv6(B, D)
        # IPv6:
        # in: IPv6(A, S3)IPv6(B, D)
        # out: IPv6(B, D)

        # get first (outer) IPv6 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IPv6)

        tx_ip = tx_pkt.getlayer(IPv6)
        tx_ip2 = tx_pkt.getlayer(IPv6, 2)

        # verify if rx'ed packet has no SRH
        self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))

        # the whole rx_ip pkt should be equal to tx_ip2
        # except for the hlim field
        #   -> adjust tx'ed hlim to expected hlim
        tx_ip2.hlim = tx_ip2.hlim - 1

        self.assertEqual(rx_ip, tx_ip2)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_End_DX4(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing End.DX4

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # End.DX4 updates the headers as follows:
        # IPv6 + SRH (SL=0):
        # in: IPv6(A, S3)SRH(S3, S2, S1; SL=0)IPv4(B, D)
        # out: IPv4(B, D)
        # IPv6:
        # in: IPv6(A, S3)IPv4(B, D)
        # out: IPv4(B, D)

        # get IPv4 header of rx'ed packet
        rx_ip = rx_pkt.getlayer(IP)

        tx_ip = tx_pkt.getlayer(IPv6)
        tx_ip2 = tx_pkt.getlayer(IP)

        # verify if rx'ed packet has no SRH
        self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))

        # the whole rx_ip pkt should be equal to tx_ip2
        # except for the ttl field and ip checksum
        #   -> adjust tx'ed ttl to expected ttl
        tx_ip2.ttl = tx_ip2.ttl - 1
        #   -> set tx'ed ip checksum to None and let scapy recompute
        tx_ip2.chksum = None
        # read back the pkt (with str()) to force computing these fields
        # probably other ways to accomplish this are possible
        tx_ip2 = IP(str(tx_ip2))

        self.assertEqual(rx_ip, tx_ip2)

        self.logger.debug("packet verification: SUCCESS")

    def compare_rx_tx_packet_End_DX2(self, tx_pkt, rx_pkt):
        """ Compare input and output packet after passing End.DX2

        :param tx_pkt: transmitted packet
        :param rx_pkt: received packet
        """
        # End.DX2 updates the headers as follows:
        # IPv6 + SRH (SL=0):
        # in: IPv6(A, S3)SRH(S3, S2, S1; SL=0)L2
        # out: L2
        # IPv6:
        # in: IPv6(A, S3)L2
        # out: L2

        # get IPv4 header of rx'ed packet
        rx_eth = rx_pkt.getlayer(Ether)

        tx_ip = tx_pkt.getlayer(IPv6)
        # we can't just get the 2nd Ether layer
        # get the Raw content and dissect it as Ether
        tx_eth1 = Ether(str(tx_pkt[Raw]))

        # verify if rx'ed packet has no SRH
        self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting))

        # the whole rx_eth pkt should be equal to tx_eth1
        self.assertEqual(rx_eth, tx_eth1)

        self.logger.debug("packet verification: SUCCESS")

    def create_stream(self, src_if, dst_if, packet_header, packet_sizes,
                      count):
        """Create SRv6 input packet stream for defined interface.

        :param VppInterface src_if: Interface to create packet stream for
        :param VppInterface dst_if: destination interface of packet stream
        :param packet_header: Layer3 scapy packet headers,
                L2 is added when not provided,
                Raw(payload) with packet_info is added
        :param list packet_sizes: packet stream pckt sizes,sequentially applied
               to packets in stream have
        :param int count: number of packets in packet stream
        :return: list of packets
        """
        self.logger.info("Creating packets")
        pkts = []
        for i in range(0, count-1):
            payload_info = self.create_packet_info(src_if, dst_if)
            self.logger.debug(
                "Creating packet with index %d" % (payload_info.index))
            payload = self.info_to_payload(payload_info)
            # add L2 header if not yet provided in packet_header
            if packet_header.getlayer(0).name == 'Ethernet':
                p = (packet_header /
                     Raw(payload))
            else:
                p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                     packet_header /
                     Raw(payload))
            size = packet_sizes[i % len(packet_sizes)]
            self.logger.debug("Packet size %d" % (size))
            self.extend_packet(p, size)
            # we need to store the packet with the automatic fields computed
            # read back the dumped packet (with str())
            # to force computing these fields
            # probably other ways are possible
            p = Ether(str(p))
            payload_info.data = p.copy()
            self.logger.debug(ppp("Created packet:", p))
            pkts.append(p)
        self.logger.info("Done creating packets")
        return pkts

    def send_and_verify_pkts(self, input, pkts, output, compare_func):
        """Send packets and verify received packets using compare_func

        :param input: ingress interface of DUT
        :param pkts: list of packets to transmit
        :param output: egress interface of DUT
        :param compare_func: function to compare in and out packets
        """
        # add traffic stream to input interface
        input.add_stream(pkts)

        # enable capture on all interfaces
        self.pg_enable_capture(self.pg_interfaces)

        # start traffic
        self.logger.info("Starting traffic")
        self.pg_start()

        # get output capture
        self.logger.info("Getting packet capture")
        capture = output.get_capture()

        # assert nothing was captured on input interface
        input.assert_nothing_captured()

        # verify captured packets
        self.verify_captured_pkts(output, capture, compare_func)

    def create_packet_header_IPv6(self, dst):
        """Create packet header: IPv6 header, UDP header

        :param dst: IPv6 destination address

        IPv6 source address is 1234::1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=dst) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv6_SRH(self, sidlist, segleft):
        """Create packet header: IPv6 header with SRH, UDP header

        :param list sidlist: segment list
        :param int segleft: segments-left field value

        IPv6 destination address is set to sidlist[segleft]
        IPv6 source addresses are 1234::1 and 4321::1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=sidlist[segleft]) /
             IPv6ExtHdrSegmentRouting(addresses=sidlist) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv6_SRH_IPv6(self, dst, sidlist, segleft):
        """Create packet header: IPv6 encapsulated in SRv6:
        IPv6 header with SRH, IPv6 header, UDP header

        :param ipv6address dst: inner IPv6 destination address
        :param list sidlist: segment list of outer IPv6 SRH
        :param int segleft: segments-left field of outer IPv6 SRH

        Outer IPv6 destination address is set to sidlist[segleft]
        IPv6 source addresses are 1234::1 and 4321::1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=sidlist[segleft]) /
             IPv6ExtHdrSegmentRouting(addresses=sidlist,
                                      segleft=segleft, nh=41) /
             IPv6(src='4321::1', dst=dst) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv6_IPv6(self, dst_inner, dst_outer):
        """Create packet header: IPv6 encapsulated in IPv6:
        IPv6 header, IPv6 header, UDP header

        :param ipv6address dst_inner: inner IPv6 destination address
        :param ipv6address dst_outer: outer IPv6 destination address

        IPv6 source addresses are 1234::1 and 4321::1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=dst_outer) /
             IPv6(src='4321::1', dst=dst_inner) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv6_SRH_SRH_IPv6(self, dst, sidlist1, segleft1,
                                               sidlist2, segleft2):
        """Create packet header: IPv6 encapsulated in SRv6 with 2 SRH:
        IPv6 header with SRH, 2nd SRH, IPv6 header, UDP header

        :param ipv6address dst: inner IPv6 destination address
        :param list sidlist1: segment list of outer IPv6 SRH
        :param int segleft1: segments-left field of outer IPv6 SRH
        :param list sidlist2: segment list of inner IPv6 SRH
        :param int segleft2: segments-left field of inner IPv6 SRH

        Outer IPv6 destination address is set to sidlist[segleft]
        IPv6 source addresses are 1234::1 and 4321::1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=sidlist1[segleft1]) /
             IPv6ExtHdrSegmentRouting(addresses=sidlist1,
                                      segleft=segleft1, nh=43) /
             IPv6ExtHdrSegmentRouting(addresses=sidlist2,
                                      segleft=segleft2, nh=41) /
             IPv6(src='4321::1', dst=dst) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv4(self, dst):
        """Create packet header: IPv4 header, UDP header

        :param dst: IPv4 destination address

        IPv4 source address is 123.1.1.1
        UDP source port and destination port are 1234
        """

        p = (IP(src='123.1.1.1', dst=dst) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv6_IPv4(self, dst_inner, dst_outer):
        """Create packet header: IPv4 encapsulated in IPv6:
        IPv6 header, IPv4 header, UDP header

        :param ipv4address dst_inner: inner IPv4 destination address
        :param ipv6address dst_outer: outer IPv6 destination address

        IPv6 source address is 1234::1
        IPv4 source address is 123.1.1.1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=dst_outer) /
             IP(src='123.1.1.1', dst=dst_inner) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_IPv6_SRH_IPv4(self, dst, sidlist, segleft):
        """Create packet header: IPv4 encapsulated in SRv6:
        IPv6 header with SRH, IPv4 header, UDP header

        :param ipv4address dst: inner IPv4 destination address
        :param list sidlist: segment list of outer IPv6 SRH
        :param int segleft: segments-left field of outer IPv6 SRH

        Outer IPv6 destination address is set to sidlist[segleft]
        IPv6 source address is 1234::1
        IPv4 source address is 123.1.1.1
        UDP source port and destination port are 1234
        """

        p = (IPv6(src='1234::1', dst=sidlist[segleft]) /
             IPv6ExtHdrSegmentRouting(addresses=sidlist,
                                      segleft=segleft, nh=4) /
             IP(src='123.1.1.1', dst=dst) /
             UDP(sport=1234, dport=1234))
        return p

    def create_packet_header_L2(self, vlan=0):
        """Create packet header: L2 header

        :param vlan: if vlan!=0 then add 802.1q header
        """
        # Note: the dst addr ('00:55:44:33:22:11') is used in
        # the compare function compare_rx_tx_packet_T_Encaps_L2
        # to detect presence of L2 in SRH payload
        p = Ether(src='00:11:22:33:44:55', dst='00:55:44:33:22:11')
        etype = 0x8137  # IPX
        if vlan:
            # add 802.1q layer
            p /= Dot1Q(vlan=vlan, type=etype)
        else:
            p.type = etype
        return p

    def create_packet_header_IPv6_SRH_L2(self, sidlist, segleft, vlan=0):
        """Create packet header: L2 encapsulated in SRv6:
        IPv6 header with SRH, L2

        :param list sidlist: segment list of outer IPv6 SRH
        :param int segleft: segments-left field of outer IPv6 SRH
        :param vlan: L2 vlan; if vlan!=0 then add 802.1q header

        Outer IPv6 destination address is set to sidlist[segleft]
        IPv6 source address is 1234::1
        """
        eth = Ether(src='00:11:22:33:44:55', dst='00:55:44:33:22:11')
        etype = 0x8137  # IPX
        if vlan:
            # add 802.1q layer
            eth /= Dot1Q(vlan=vlan, type=etype)
        else:
            eth.type = etype

        p = (IPv6(src='1234::1', dst=sidlist[segleft]) /
             IPv6ExtHdrSegmentRouting(addresses=sidlist,
                                      segleft=segleft, nh=59) /
             eth)
        return p

    def create_packet_header_IPv6_L2(self, dst_outer, vlan=0):
        """Create packet header: L2 encapsulated in IPv6:
        IPv6 header, L2

        :param ipv6address dst_outer: outer IPv6 destination address
        :param vlan: L2 vlan; if vlan!=0 then add 802.1q header
        """
        eth = Ether(src='00:11:22:33:44:55', dst='00:55:44:33:22:11')
        etype = 0x8137  # IPX
        if vlan:
            # add 802.1q layer
            eth /= Dot1Q(vlan=vlan, type=etype)
        else:
            eth.type = etype

        p = (IPv6(src='1234::1', dst=dst_outer, nh=59) / eth)
        return p

    def get_payload_info(self, packet):
        """ Extract the payload_info from the packet
        """
        # in most cases, payload_info is in packet[Raw]
        # but packet[Raw] gives the complete payload
        # (incl L2 header) for the T.Encaps L2 case
        try:
            payload_info = self.payload_to_info(str(packet[Raw]))

        except:
            # remote L2 header from packet[Raw]:
            # take packet[Raw], convert it to an Ether layer
            # and then extract Raw from it
            payload_info = self.payload_to_info(
                str(Ether(str(packet[Raw]))[Raw]))

        return payload_info

    def verify_captured_pkts(self, dst_if, capture, compare_func):
        """
        Verify captured packet stream for specified interface.
        Compare ingress with egress packets using the specified compare fn

        :param dst_if: egress interface of DUT
        :param capture: captured packets
        :param compare_func: function to compare in and out packet
        """
        self.logger.info("Verifying capture on interface %s using function %s"
                         % (dst_if.name, compare_func.func_name))

        last_info = dict()
        for i in self.pg_interfaces:
            last_info[i.sw_if_index] = None
        dst_sw_if_index = dst_if.sw_if_index

        for packet in capture:
            try:
                # extract payload_info from packet's payload
                payload_info = self.get_payload_info(packet)
                packet_index = payload_info.index

                self.logger.debug("Verifying packet with index %d"
                                  % (packet_index))
                # packet should have arrived on the expected interface
                self.assertEqual(payload_info.dst, dst_sw_if_index)
                self.logger.debug(
                    "Got packet on interface %s: src=%u (idx=%u)" %
                    (dst_if.name, payload_info.src, packet_index))

                # search for payload_info with same src and dst if_index
                # this will give us the transmitted packet
                next_info = self.get_next_packet_info_for_interface2(
                    payload_info.src, dst_sw_if_index,
                    last_info[payload_info.src])
                last_info[payload_info.src] = next_info
                # next_info should not be None
                self.assertTrue(next_info is not None)
                # index of tx and rx packets should be equal
                self.assertEqual(packet_index, next_info.index)
                # data field of next_info contains the tx packet
                txed_packet = next_info.data

                self.logger.debug(ppp("Transmitted packet:",
                                      txed_packet))  # ppp=Pretty Print Packet

                self.logger.debug(ppp("Received packet:", packet))

                # compare rcvd packet with expected packet using compare_func
                compare_func(txed_packet, packet)

            except:
                print packet.command()
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise

        # have all expected packets arrived?
        for i in self.pg_interfaces:
            remaining_packet = self.get_next_packet_info_for_interface2(
                i.sw_if_index, dst_sw_if_index, last_info[i.sw_if_index])
            self.assertTrue(remaining_packet is None,
                            "Interface %s: Packet expected from interface %s "
                            "didn't arrive" % (dst_if.name, i.name))


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