#!/usr/bin/env python3
import binascii
import random
import socket
import unittest

import scapy.compat
from scapy.contrib.mpls import MPLS
from scapy.layers.inet import IP, UDP, TCP, ICMP, icmptypes, icmpcodes
from scapy.layers.inet6 import IPv6
from scapy.layers.l2 import Ether, Dot1Q, ARP
from scapy.packet import Raw
from six import moves

from framework import tag_fixme_vpp_workers
from framework import VppTestCase, VppTestRunner
from util import ppp
from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpMRoute, \
    VppMRoutePath, VppMplsIpBind, \
    VppMplsTable, VppIpTable, FibPathType, find_route, \
    VppIpInterfaceAddress, find_route_in_dump, find_mroute_in_dump
from vpp_ip import VppIpPuntPolicer, VppIpPuntRedirect, VppIpPathMtu
from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
from vpp_papi import vpp_papi, VppEnum
from vpp_neighbor import VppNeighbor
from vpp_lo_interface import VppLoInterface
from vpp_policer import VppPolicer, PolicerAction

NUM_PKTS = 67


class TestIPv4(VppTestCase):
    """ IPv4 Test Case """

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

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

    def setUp(self):
        """
        Perform test setup before test case.

        **Config:**
            - create 3 pg interfaces
                - untagged pg0 interface
                - Dot1Q subinterface on pg1
                - Dot1AD subinterface on pg2
            - setup interfaces:
                - put it into UP state
                - set IPv4 addresses
                - resolve neighbor address using ARP
            - configure 200 fib entries

        :ivar list interfaces: pg interfaces and subinterfaces.
        :ivar dict flows: IPv4 packet flows in test.
        """
        super(TestIPv4, self).setUp()

        # create 3 pg interfaces
        self.create_pg_interfaces(range(3))

        # create 2 subinterfaces for pg1 and pg2
        self.sub_interfaces = [
            VppDot1QSubint(self, self.pg1, 100),
            VppDot1ADSubint(self, self.pg2, 200, 300, 400)]

        # packet flows mapping pg0 -> pg1.sub, pg2.sub, etc.
        self.flows = dict()
        self.flows[self.pg0] = [self.pg1.sub_if, self.pg2.sub_if]
        self.flows[self.pg1.sub_if] = [self.pg0, self.pg2.sub_if]
        self.flows[self.pg2.sub_if] = [self.pg0, self.pg1.sub_if]

        # packet sizes
        self.pg_if_packet_sizes = [64, 1500, 9020]

        self.interfaces = list(self.pg_interfaces)
        self.interfaces.extend(self.sub_interfaces)

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

        # config 2M FIB entries

    def tearDown(self):
        """Run standard test teardown and log ``show ip arp``."""
        super(TestIPv4, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show ip4 neighbors"))
        # info(self.vapi.cli("show ip fib"))  # many entries

    def modify_packet(self, src_if, packet_size, pkt):
        """Add load, set destination IP and extend packet to required packet
        size for defined interface.

        :param VppInterface src_if: Interface to create packet for.
        :param int packet_size: Required packet size.
        :param Scapy pkt: Packet to be modified.
        """
        dst_if_idx = int(packet_size / 10 % 2)
        dst_if = self.flows[src_if][dst_if_idx]
        info = self.create_packet_info(src_if, dst_if)
        payload = self.info_to_payload(info)
        p = pkt/Raw(payload)
        p[IP].dst = dst_if.remote_ip4
        info.data = p.copy()
        if isinstance(src_if, VppSubInterface):
            p = src_if.add_dot1_layer(p)
        self.extend_packet(p, packet_size)

        return p

    def create_stream(self, src_if):
        """Create input packet stream for defined interface.

        :param VppInterface src_if: Interface to create packet stream for.
        """
        hdr_ext = 4 if isinstance(src_if, VppSubInterface) else 0
        pkt_tmpl = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                    IP(src=src_if.remote_ip4) /
                    UDP(sport=1234, dport=1234))

        pkts = [self.modify_packet(src_if, i, pkt_tmpl)
                for i in moves.range(self.pg_if_packet_sizes[0],
                                     self.pg_if_packet_sizes[1], 10)]
        pkts_b = [self.modify_packet(src_if, i, pkt_tmpl)
                  for i in moves.range(self.pg_if_packet_sizes[1] + hdr_ext,
                                       self.pg_if_packet_sizes[2] + hdr_ext,
                                       50)]
        pkts.extend(pkts_b)

        return pkts

    def verify_capture(self, dst_if, capture):
        """Verify captured input packet stream for defined interface.

        :param VppInterface dst_if: Interface to verify captured packet stream
            for.
        :param list capture: Captured packet stream.
        """
        self.logger.info("Verifying capture on interface %s" % dst_if.name)
        last_info = dict()
        for i in self.interfaces:
            last_info[i.sw_if_index] = None
        is_sub_if = False
        dst_sw_if_index = dst_if.sw_if_index
        if hasattr(dst_if, 'parent'):
            is_sub_if = True
        for packet in capture:
            if is_sub_if:
                # Check VLAN tags and Ethernet header
                packet = dst_if.remove_dot1_layer(packet)
            self.assertTrue(Dot1Q not in packet)
            try:
                ip = packet[IP]
                udp = packet[UDP]
                payload_info = self.payload_to_info(packet[Raw])
                packet_index = payload_info.index
                self.assertEqual(payload_info.dst, dst_sw_if_index)
                self.logger.debug(
                    "Got packet on port %s: src=%u (id=%u)" %
                    (dst_if.name, payload_info.src, packet_index))
                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
                self.assertTrue(next_info is not None)
                self.assertEqual(packet_index, next_info.index)
                saved_packet = next_info.data
                # Check standard fields
                self.assertEqual(ip.src, saved_packet[IP].src)
                self.assertEqual(ip.dst, saved_packet[IP].dst)
                self.assertEqual(udp.sport, saved_packet[UDP].sport)
                self.assertEqual(udp.dport, saved_packet[UDP].dport)
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise
        for i in self.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))

    def test_fib(self):
        """ IPv4 FIB test

        Test scenario:

            - Create IPv4 stream for pg0 interface
            - Create IPv4 tagged streams for pg1's and pg2's sub-interface.
            - Send and verify received packets on each interface.
        """

        pkts = self.create_stream(self.pg0)
        self.pg0.add_stream(pkts)

        for i in self.sub_interfaces:
            pkts = self.create_stream(i)
            i.parent.add_stream(pkts)

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

        pkts = self.pg0.get_capture()
        self.verify_capture(self.pg0, pkts)

        for i in self.sub_interfaces:
            pkts = i.parent.get_capture()
            self.verify_capture(i, pkts)


class TestIPv4RouteLookup(VppTestCase):
    """ IPv4 Route Lookup Test Case """
    routes = []

    def route_lookup(self, prefix, exact):
        return self.vapi.api(self.vapi.papi.ip_route_lookup,
                             {
                                 'table_id': 0,
                                 'exact': exact,
                                 'prefix': prefix,
                             })

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

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

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

        drop_nh = VppRoutePath("127.0.0.1", 0xffffffff,
                               type=FibPathType.FIB_PATH_TYPE_DROP)

        # Add 3 routes
        r = VppIpRoute(self, "1.1.0.0", 16, [drop_nh])
        r.add_vpp_config()
        self.routes.append(r)

        r = VppIpRoute(self, "1.1.1.0", 24, [drop_nh])
        r.add_vpp_config()
        self.routes.append(r)

        r = VppIpRoute(self, "1.1.1.1", 32, [drop_nh])
        r.add_vpp_config()
        self.routes.append(r)

    def tearDown(self):
        # Remove the routes we added
        for r in self.routes:
            r.remove_vpp_config()

        super(TestIPv4RouteLookup, self).tearDown()

    def test_exact_match(self):
        # Verify we find the host route
        prefix = "1.1.1.1/32"
        result = self.route_lookup(prefix, True)
        assert (prefix == str(result.route.prefix))

        # Verify we find a middle prefix route
        prefix = "1.1.1.0/24"
        result = self.route_lookup(prefix, True)
        assert (prefix == str(result.route.prefix))

        # Verify we do not find an available LPM.
        with self.vapi.assert_negative_api_retval():
            self.route_lookup("1.1.1.2/32", True)

    def test_longest_prefix_match(self):
        # verify we find lpm
        lpm_prefix = "1.1.1.0/24"
        result = self.route_lookup("1.1.1.2/32", False)
        assert (lpm_prefix == str(result.route.prefix))

        # Verify we find the exact when not requested
        result = self.route_lookup(lpm_prefix, False)
        assert (lpm_prefix == str(result.route.prefix))

        # Can't seem to delete the default route so no negative LPM test.


class TestIPv4IfAddrRoute(VppTestCase):
    """ IPv4 Interface Addr Route Test Case """

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

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

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

        # create 1 pg interface
        self.create_pg_interfaces(range(1))

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

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

    def test_ipv4_ifaddrs_same_prefix(self):
        """ IPv4 Interface Addresses Same Prefix test

        Test scenario:

            - Verify no route in FIB for prefix 10.10.10.0/24
            - Configure IPv4 address 10.10.10.10/24 on an interface
            - Verify route in FIB for prefix 10.10.10.0/24
            - Configure IPv4 address 10.10.10.20/24 on an interface
            - Delete 10.10.10.10/24 from interface
            - Verify route in FIB for prefix 10.10.10.0/24
            - Delete 10.10.10.20/24 from interface
            - Verify no route in FIB for prefix 10.10.10.0/24
        """

        # create two addresses, verify route not present
        if_addr1 = VppIpInterfaceAddress(self, self.pg0, "10.10.10.10", 24)
        if_addr2 = VppIpInterfaceAddress(self, self.pg0, "10.10.10.20", 24)
        self.assertFalse(if_addr1.query_vpp_config())  # 10.10.10.10/24
        self.assertFalse(find_route(self, "10.10.10.10", 32))
        self.assertFalse(find_route(self, "10.10.10.20", 32))
        self.assertFalse(find_route(self, "10.10.10.255", 32))
        self.assertFalse(find_route(self, "10.10.10.0", 32))

        # configure first address, verify route present
        if_addr1.add_vpp_config()
        self.assertTrue(if_addr1.query_vpp_config())  # 10.10.10.10/24
        self.assertTrue(find_route(self, "10.10.10.10", 32))
        self.assertFalse(find_route(self, "10.10.10.20", 32))
        self.assertTrue(find_route(self, "10.10.10.255", 32))
        self.assertTrue(find_route(self, "10.10.10.0", 32))

        # configure second address, delete first, verify route not removed
        if_addr2.add_vpp_config()
        if_addr1.remove_vpp_config()
        self.assertFalse(if_addr1.query_vpp_config())  # 10.10.10.10/24
        self.assertTrue(if_addr2.query_vpp_config())  # 10.10.10.20/24
        self.assertFalse(find_route(self, "10.10.10.10", 32))
        self.assertTrue(find_route(self, "10.10.10.20", 32))
        self.assertTrue(find_route(self, "10.10.10.255", 32))
        self.assertTrue(find_route(self, "10.10.10.0", 32))

        # delete second address, verify route removed
        if_addr2.remove_vpp_config()
        self.assertFalse(if_addr2.query_vpp_config())  # 10.10.10.20/24
        self.assertFalse(find_route(self, "10.10.10.10", 32))
        self.assertFalse(find_route(self, "10.10.10.20", 32))
        self.assertFalse(find_route(self, "10.10.10.255", 32))
        self.assertFalse(find_route(self, "10.10.10.0", 32))

    def test_ipv4_ifaddr_route(self):
        """ IPv4 Interface Address Route test

        Test scenario:

            - Create loopback
            - Configure IPv4 address on loopback
            - Verify that address is not in the FIB
            - Bring loopback up
            - Verify that address is in the FIB now
            - Bring loopback down
            - Verify that address is not in the FIB anymore
            - Bring loopback up
            - Configure IPv4 address on loopback
            - Verify that address is in the FIB now
        """

        # create a loopback and configure IPv4
        loopbacks = self.create_loopback_interfaces(1)
        lo_if = self.lo_interfaces[0]

        lo_if.local_ip4_prefix_len = 32
        lo_if.config_ip4()

        # The intf was down when addr was added -> entry not in FIB
        fib4_dump = self.vapi.ip_route_dump(0)
        self.assertFalse(lo_if.is_ip4_entry_in_fib_dump(fib4_dump))

        # When intf is brought up, entry is added
        lo_if.admin_up()
        fib4_dump = self.vapi.ip_route_dump(0)
        self.assertTrue(lo_if.is_ip4_entry_in_fib_dump(fib4_dump))

        # When intf is brought down, entry is removed
        lo_if.admin_down()
        fib4_dump = self.vapi.ip_route_dump(0)
        self.assertFalse(lo_if.is_ip4_entry_in_fib_dump(fib4_dump))

        # Remove addr, bring up interface, re-add -> entry in FIB
        lo_if.unconfig_ip4()
        lo_if.admin_up()
        lo_if.config_ip4()
        fib4_dump = self.vapi.ip_route_dump(0)
        self.assertTrue(lo_if.is_ip4_entry_in_fib_dump(fib4_dump))

    def test_ipv4_ifaddr_del(self):
        """ Delete an interface address that does not exist """

        loopbacks = self.create_loopback_interfaces(1)
        lo = self.lo_interfaces[0]

        lo.config_ip4()
        lo.admin_up()

        #
        # try and remove pg0's subnet from lo
        #
        with self.vapi.assert_negative_api_retval():
            self.vapi.sw_interface_add_del_address(
                sw_if_index=lo.sw_if_index,
                prefix=self.pg0.local_ip4_prefix,
                is_add=0)


class TestICMPEcho(VppTestCase):
    """ ICMP Echo Test Case """

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

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

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

        # create 1 pg interface
        self.create_pg_interfaces(range(1))

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

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

    def test_icmp_echo(self):
        """ VPP replies to ICMP Echo Request

        Test scenario:

            - Receive ICMP Echo Request message on pg0 interface.
            - Check outgoing ICMP Echo Reply message on pg0 interface.
        """

        icmp_id = 0xb
        icmp_seq = 5
        icmp_load = b'\x0a' * 18
        p_echo_request = (Ether(src=self.pg0.remote_mac,
                                dst=self.pg0.local_mac) /
                          IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
                          ICMP(id=icmp_id, seq=icmp_seq) /
                          Raw(load=icmp_load))

        self.pg0.add_stream(p_echo_request)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rx = self.pg0.get_capture(1)
        rx = rx[0]
        ether = rx[Ether]
        ipv4 = rx[IP]
        icmp = rx[ICMP]

        self.assertEqual(ether.src, self.pg0.local_mac)
        self.assertEqual(ether.dst, self.pg0.remote_mac)

        self.assertEqual(ipv4.src, self.pg0.local_ip4)
        self.assertEqual(ipv4.dst, self.pg0.remote_ip4)

        self.assertEqual(icmptypes[icmp.type], "echo-reply")
        self.assertEqual(icmp.id, icmp_id)
        self.assertEqual(icmp.seq, icmp_seq)
        self.assertEqual(icmp[Raw].load, icmp_load)


class TestIPv4FibCrud(VppTestCase):
    """ FIB - add/update/delete - ip4 routes

    Test scenario:
        - add 1k,
        - del 100,
        - add new 1k,
        - del 1.5k

    ..note:: Python API is too slow to add many routes, needs replacement.
    """

    def config_fib_many_to_one(self, start_dest_addr, next_hop_addr,
                               count, start=0):
        """

        :param start_dest_addr:
        :param next_hop_addr:
        :param count:
        :return list: added ips with 32 prefix
        """
        routes = []
        for i in range(count):
            r = VppIpRoute(self, start_dest_addr % (i + start), 32,
                           [VppRoutePath(next_hop_addr, 0xffffffff)])
            r.add_vpp_config()
            routes.append(r)
        return routes

    def unconfig_fib_many_to_one(self, start_dest_addr, next_hop_addr,
                                 count, start=0):

        routes = []
        for i in range(count):
            r = VppIpRoute(self, start_dest_addr % (i + start), 32,
                           [VppRoutePath(next_hop_addr, 0xffffffff)])
            r.remove_vpp_config()
            routes.append(r)
        return routes

    def create_stream(self, src_if, dst_if, routes, count):
        pkts = []

        for _ in range(count):
            dst_addr = random.choice(routes).prefix.network_address
            info = self.create_packet_info(src_if, dst_if)
            payload = self.info_to_payload(info)
            p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
                 IP(src=src_if.remote_ip4, dst=str(dst_addr)) /
                 UDP(sport=1234, dport=1234) /
                 Raw(payload))
            info.data = p.copy()
            self.extend_packet(p, random.choice(self.pg_if_packet_sizes))
            pkts.append(p)

        return pkts

    def _find_ip_match(self, find_in, pkt):
        for p in find_in:
            if self.payload_to_info(p[Raw]) == \
                    self.payload_to_info(pkt[Raw]):
                if p[IP].src != pkt[IP].src:
                    break
                if p[IP].dst != pkt[IP].dst:
                    break
                if p[UDP].sport != pkt[UDP].sport:
                    break
                if p[UDP].dport != pkt[UDP].dport:
                    break
                return p
        return None

    def verify_capture(self, dst_interface, received_pkts, expected_pkts):
        self.assertEqual(len(received_pkts), len(expected_pkts))
        to_verify = list(expected_pkts)
        for p in received_pkts:
            self.assertEqual(p.src, dst_interface.local_mac)
            self.assertEqual(p.dst, dst_interface.remote_mac)
            x = self._find_ip_match(to_verify, p)
            to_verify.remove(x)
        self.assertListEqual(to_verify, [])

    def verify_route_dump(self, routes):
        for r in routes:
            self.assertTrue(find_route(self,
                                       r.prefix.network_address,
                                       r.prefix.prefixlen))

    def verify_not_in_route_dump(self, routes):
        for r in routes:
            self.assertFalse(find_route(self,
                                        r.prefix.network_address,
                                        r.prefix.prefixlen))

    @classmethod
    def setUpClass(cls):
        """
        #. Create and initialize 3 pg interfaces.
        #. initialize class attributes configured_routes and deleted_routes
           to store information between tests.
        """
        super(TestIPv4FibCrud, cls).setUpClass()

        try:
            # create 3 pg interfaces
            cls.create_pg_interfaces(range(3))

            cls.interfaces = list(cls.pg_interfaces)

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

            cls.configured_routes = []
            cls.deleted_routes = []
            cls.pg_if_packet_sizes = [64, 512, 1518, 9018]

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

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

    def setUp(self):
        super(TestIPv4FibCrud, self).setUp()
        self.reset_packet_infos()

        self.configured_routes = []
        self.deleted_routes = []

    def test_1_add_routes(self):
        """ Add 1k routes """

        # add 100 routes check with traffic script.
        self.configured_routes.extend(self.config_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 100))

        self.verify_route_dump(self.configured_routes)

        self.stream_1 = self.create_stream(
            self.pg1, self.pg0, self.configured_routes, 100)
        self.stream_2 = self.create_stream(
            self.pg2, self.pg0, self.configured_routes, 100)
        self.pg1.add_stream(self.stream_1)
        self.pg2.add_stream(self.stream_2)

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

        pkts = self.pg0.get_capture(len(self.stream_1) + len(self.stream_2))
        self.verify_capture(self.pg0, pkts, self.stream_1 + self.stream_2)

    def test_2_del_routes(self):
        """ Delete 100 routes

        - delete 10 routes check with traffic script.
        """
        # config 1M FIB entries
        self.configured_routes.extend(self.config_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 100))
        self.deleted_routes.extend(self.unconfig_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 10, start=10))
        for x in self.deleted_routes:
            self.configured_routes.remove(x)

        self.verify_route_dump(self.configured_routes)

        self.stream_1 = self.create_stream(
            self.pg1, self.pg0, self.configured_routes, 100)
        self.stream_2 = self.create_stream(
            self.pg2, self.pg0, self.configured_routes, 100)
        self.stream_3 = self.create_stream(
            self.pg1, self.pg0, self.deleted_routes, 100)
        self.stream_4 = self.create_stream(
            self.pg2, self.pg0, self.deleted_routes, 100)
        self.pg1.add_stream(self.stream_1 + self.stream_3)
        self.pg2.add_stream(self.stream_2 + self.stream_4)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        pkts = self.pg0.get_capture(len(self.stream_1) + len(self.stream_2))
        self.verify_capture(self.pg0, pkts, self.stream_1 + self.stream_2)

    def test_3_add_new_routes(self):
        """ Add 1k routes

        - re-add 5 routes check with traffic script.
        - add 100 routes check with traffic script.
        """
        # config 1M FIB entries
        self.configured_routes.extend(self.config_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 100))
        self.deleted_routes.extend(self.unconfig_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 10, start=10))
        for x in self.deleted_routes:
            self.configured_routes.remove(x)

        tmp = self.config_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 5, start=10)
        self.configured_routes.extend(tmp)
        for x in tmp:
            self.deleted_routes.remove(x)

        self.configured_routes.extend(self.config_fib_many_to_one(
            "10.0.1.%d", self.pg0.remote_ip4, 100))

        self.verify_route_dump(self.configured_routes)

        self.stream_1 = self.create_stream(
            self.pg1, self.pg0, self.configured_routes, 300)
        self.stream_2 = self.create_stream(
            self.pg2, self.pg0, self.configured_routes, 300)
        self.stream_3 = self.create_stream(
            self.pg1, self.pg0, self.deleted_routes, 100)
        self.stream_4 = self.create_stream(
            self.pg2, self.pg0, self.deleted_routes, 100)

        self.pg1.add_stream(self.stream_1 + self.stream_3)
        self.pg2.add_stream(self.stream_2 + self.stream_4)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        pkts = self.pg0.get_capture(len(self.stream_1) + len(self.stream_2))
        self.verify_capture(self.pg0, pkts, self.stream_1 + self.stream_2)

        # delete 5 routes check with traffic script.
        # add 100 routes check with traffic script.
        self.deleted_routes.extend(self.unconfig_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 15))
        self.deleted_routes.extend(self.unconfig_fib_many_to_one(
            "10.0.0.%d", self.pg0.remote_ip4, 85))
        self.deleted_routes.extend(self.unconfig_fib_many_to_one(
            "10.0.1.%d", self.pg0.remote_ip4, 100))
        self.verify_not_in_route_dump(self.deleted_routes)


class TestIPNull(VppTestCase):
    """ IPv4 routes via NULL """

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

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

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

        # create 2 pg interfaces
        self.create_pg_interfaces(range(2))

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

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

    def test_ip_null(self):
        """ IP NULL route """

        #
        # A route via IP NULL that will reply with ICMP unreachables
        #
        ip_unreach = VppIpRoute(
            self, "10.0.0.1", 32,
            [VppRoutePath("0.0.0.0",
                          0xffffffff,
                          type=FibPathType.FIB_PATH_TYPE_ICMP_UNREACH)])
        ip_unreach.add_vpp_config()

        p_unreach = (Ether(src=self.pg0.remote_mac,
                           dst=self.pg0.local_mac) /
                     IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
                     UDP(sport=1234, dport=1234) /
                     Raw(b'\xa5' * 100))
        self.pg0.add_stream(p_unreach)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rx = self.pg0.get_capture(1)
        rx = rx[0]
        icmp = rx[ICMP]

        self.assertEqual(icmptypes[icmp.type], "dest-unreach")
        self.assertEqual(icmpcodes[icmp.type][icmp.code], "host-unreachable")
        self.assertEqual(icmp.src, self.pg0.remote_ip4)
        self.assertEqual(icmp.dst, "10.0.0.1")

        #
        # ICMP replies are rate limited. so sit and spin.
        #
        self.sleep(1)

        #
        # A route via IP NULL that will reply with ICMP prohibited
        #
        ip_prohibit = VppIpRoute(
            self, "10.0.0.2", 32,
            [VppRoutePath("0.0.0.0",
                          0xffffffff,
                          type=FibPathType.FIB_PATH_TYPE_ICMP_PROHIBIT)])
        ip_prohibit.add_vpp_config()

        p_prohibit = (Ether(src=self.pg0.remote_mac,
                            dst=self.pg0.local_mac) /
                      IP(src=self.pg0.remote_ip4, dst="10.0.0.2") /
                      UDP(sport=1234, dport=1234) /
                      Raw(b'\xa5' * 100))

        self.pg0.add_stream(p_prohibit)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rx = self.pg0.get_capture(1)

        rx = rx[0]
        icmp = rx[ICMP]

        self.assertEqual(icmptypes[icmp.type], "dest-unreach")
        self.assertEqual(icmpcodes[icmp.type][icmp.code], "host-prohibited")
        self.assertEqual(icmp.src, self.pg0.remote_ip4)
        self.assertEqual(icmp.dst, "10.0.0.2")

    def test_ip_drop(self):
        """ IP Drop Routes """

        p = (Ether(src=self.pg0.remote_mac,
                   dst=self.pg0.local_mac) /
             IP(src=self.pg0.remote_ip4, dst="1.1.1.1") /
             UDP(sport=1234, dport=1234) /
             Raw(b'\xa5' * 100))

        r1 = VppIpRoute(self, "1.1.1.0", 24,
                        [VppRoutePath(self.pg1.remote_ip4,
                                      self.pg1.sw_if_index)])
        r1.add_vpp_config()

        rx = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)

        #
        # insert a more specific as a drop
        #
        r2 = VppIpRoute(self, "1.1.1.1", 32,
                        [VppRoutePath("0.0.0.0",
                                      0xffffffff,
                                      type=FibPathType.FIB_PATH_TYPE_DROP)])
        r2.add_vpp_config()

        self.send_and_assert_no_replies(self.pg0, p * NUM_PKTS, "Drop Route")
        r2.remove_vpp_config()
        rx = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)


class TestIPDisabled(VppTestCase):
    """ IPv4 disabled """

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

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

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

        # create 2 pg interfaces
        self.create_pg_interfaces(range(2))

        # PG0 is IP enalbed
        self.pg0.admin_up()
        self.pg0.config_ip4()
        self.pg0.resolve_arp()

        # PG 1 is not IP enabled
        self.pg1.admin_up()

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

    def test_ip_disabled(self):
        """ IP Disabled """

        MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
        MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t

        #
        # An (S,G).
        # one accepting interface, pg0, 2 forwarding interfaces
        #
        route_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1", 32,
            MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
            [VppMRoutePath(self.pg1.sw_if_index,
                           MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
             VppMRoutePath(self.pg0.sw_if_index,
                           MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
        route_232_1_1_1.add_vpp_config()

        pu = (Ether(src=self.pg1.remote_mac,
                    dst=self.pg1.local_mac) /
              IP(src="10.10.10.10", dst=self.pg0.remote_ip4) /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))
        pm = (Ether(src=self.pg1.remote_mac,
                    dst=self.pg1.local_mac) /
              IP(src="10.10.10.10", dst="232.1.1.1") /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))

        #
        # PG1 does not forward IP traffic
        #
        self.send_and_assert_no_replies(self.pg1, pu, "IP disabled")
        self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")

        #
        # IP enable PG1
        #
        self.pg1.config_ip4()

        #
        # Now we get packets through
        #
        self.pg1.add_stream(pu)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg0.get_capture(1)

        self.pg1.add_stream(pm)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg0.get_capture(1)

        #
        # Disable PG1
        #
        self.pg1.unconfig_ip4()

        #
        # PG1 does not forward IP traffic
        #
        self.send_and_assert_no_replies(self.pg1, pu, "IP disabled")
        self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")


class TestIPSubNets(VppTestCase):
    """ IPv4 Subnets """

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

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

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

        # create a 2 pg interfaces
        self.create_pg_interfaces(range(2))

        # pg0 we will use to experiment
        self.pg0.admin_up()

        # pg1 is setup normally
        self.pg1.admin_up()
        self.pg1.config_ip4()
        self.pg1.resolve_arp()

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

    def test_ip_sub_nets(self):
        """ IP Sub Nets """

        #
        # Configure a covering route to forward so we know
        # when we are dropping
        #
        cover_route = VppIpRoute(self, "10.0.0.0", 8,
                                 [VppRoutePath(self.pg1.remote_ip4,
                                               self.pg1.sw_if_index)])
        cover_route.add_vpp_config()

        p = (Ether(src=self.pg1.remote_mac,
                   dst=self.pg1.local_mac) /
             IP(dst="10.10.10.10", src=self.pg0.local_ip4) /
             UDP(sport=1234, dport=1234) /
             Raw(b'\xa5' * 100))

        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)

        #
        # Configure some non-/24 subnets on an IP interface
        #
        ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10")

        self.vapi.sw_interface_add_del_address(
            sw_if_index=self.pg0.sw_if_index,
            prefix="10.10.10.10/16")

        pn = (Ether(src=self.pg1.remote_mac,
                    dst=self.pg1.local_mac) /
              IP(dst="10.10.0.0", src=self.pg0.local_ip4) /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))
        pb = (Ether(src=self.pg1.remote_mac,
                    dst=self.pg1.local_mac) /
              IP(dst="10.10.255.255", src=self.pg0.local_ip4) /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))

        self.send_and_assert_no_replies(self.pg1, pn, "IP Network address")
        self.send_and_assert_no_replies(self.pg1, pb, "IP Broadcast address")

        # remove the sub-net and we are forwarding via the cover again
        self.vapi.sw_interface_add_del_address(
            sw_if_index=self.pg0.sw_if_index,
            prefix="10.10.10.10/16",
            is_add=0)

        self.pg1.add_stream(pn)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)
        self.pg1.add_stream(pb)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)

        #
        # A /31 is a special case where the 'other-side' is an attached host
        # packets to that peer generate ARP requests
        #
        ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10")

        self.vapi.sw_interface_add_del_address(
            sw_if_index=self.pg0.sw_if_index,
            prefix="10.10.10.10/31")

        pn = (Ether(src=self.pg1.remote_mac,
                    dst=self.pg1.local_mac) /
              IP(dst="10.10.10.11", src=self.pg0.local_ip4) /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))

        self.pg1.add_stream(pn)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg0.get_capture(1)
        rx[ARP]

        # remove the sub-net and we are forwarding via the cover again
        self.vapi.sw_interface_add_del_address(
            sw_if_index=self.pg0.sw_if_index,
            prefix="10.10.10.10/31", is_add=0)

        self.pg1.add_stream(pn)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)


class TestIPLoadBalance(VppTestCase):
    """ IPv4 Load-Balancing """

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

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

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

        self.create_pg_interfaces(range(5))
        mpls_tbl = VppMplsTable(self, 0)
        mpls_tbl.add_vpp_config()

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

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

    def total_len(self, rxs):
        n = 0
        for rx in rxs:
            n += len(rx)
        return n

    def test_ip_load_balance(self):
        """ IP Load-Balancing """

        fhc = VppEnum.vl_api_ip_flow_hash_config_t
        af = VppEnum.vl_api_address_family_t

        #
        # An array of packets that differ only in the destination port
        #
        port_ip_pkts = []
        port_mpls_pkts = []

        #
        # An array of packets that differ only in the source address
        #
        src_ip_pkts = []
        src_mpls_pkts = []

        for ii in range(NUM_PKTS):
            port_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.1") /
                           UDP(sport=1234, dport=1234 + ii) /
                           Raw(b'\xa5' * 100))
            port_ip_pkts.append((Ether(src=self.pg0.remote_mac,
                                       dst=self.pg0.local_mac) /
                                 port_ip_hdr))
            port_mpls_pkts.append((Ether(src=self.pg0.remote_mac,
                                         dst=self.pg0.local_mac) /
                                   MPLS(label=66, ttl=2) /
                                   port_ip_hdr))

            src_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.%d" % ii) /
                          UDP(sport=1234, dport=1234) /
                          Raw(b'\xa5' * 100))
            src_ip_pkts.append((Ether(src=self.pg0.remote_mac,
                                      dst=self.pg0.local_mac) /
                                src_ip_hdr))
            src_mpls_pkts.append((Ether(src=self.pg0.remote_mac,
                                        dst=self.pg0.local_mac) /
                                  MPLS(label=66, ttl=2) /
                                  src_ip_hdr))

        route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
                                    [VppRoutePath(self.pg1.remote_ip4,
                                                  self.pg1.sw_if_index),
                                     VppRoutePath(self.pg2.remote_ip4,
                                                  self.pg2.sw_if_index)])
        route_10_0_0_1.add_vpp_config()

        binding = VppMplsIpBind(self, 66, "10.0.0.1", 32)
        binding.add_vpp_config()

        #
        # inject the packet on pg0 - expect load-balancing across the 2 paths
        #  - since the default hash config is to use IP src,dst and port
        #    src,dst
        # We are not going to ensure equal amounts of packets across each link,
        # since the hash algorithm is statistical and therefore this can never
        # be guaranteed. But with 64 different packets we do expect some
        # balancing. So instead just ensure there is traffic on each link.
        #
        rx = self.send_and_expect_load_balancing(self.pg0, port_ip_pkts,
                                                 [self.pg1, self.pg2])
        n_ip_pg0 = len(rx[0])
        self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
                                            [self.pg1, self.pg2])
        self.send_and_expect_load_balancing(self.pg0, port_mpls_pkts,
                                            [self.pg1, self.pg2])
        rx = self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
                                                 [self.pg1, self.pg2])
        n_mpls_pg0 = len(rx[0])

        #
        # change the router ID and expect the distribution changes
        #
        self.vapi.set_ip_flow_hash_router_id(router_id=0x11111111)

        rx = self.send_and_expect_load_balancing(self.pg0, port_ip_pkts,
                                                 [self.pg1, self.pg2])
        self.assertNotEqual(n_ip_pg0, len(rx[0]))

        rx = self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
                                                 [self.pg1, self.pg2])
        self.assertNotEqual(n_mpls_pg0, len(rx[0]))

        #
        # change the flow hash config so it's only IP src,dst
        #  - now only the stream with differing source address will
        #    load-balance
        #
        self.vapi.set_ip_flow_hash_v2(
            af=af.ADDRESS_IP4,
            table_id=0,
            flow_hash_config=(fhc.IP_API_FLOW_HASH_SRC_IP |
                              fhc.IP_API_FLOW_HASH_DST_IP |
                              fhc.IP_API_FLOW_HASH_PROTO))

        self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
                                            [self.pg1, self.pg2])
        self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
                                            [self.pg1, self.pg2])

        self.send_and_expect_only(self.pg0, port_ip_pkts, self.pg2)

        #
        # change the flow hash config back to defaults
        #
        self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1,
                                   proto=1, sport=1, dport=1)

        #
        # Recursive prefixes
        #  - testing that 2 stages of load-balancing occurs and there is no
        #    polarisation (i.e. only 2 of 4 paths are used)
        #
        port_pkts = []
        src_pkts = []

        for ii in range(257):
            port_pkts.append((Ether(src=self.pg0.remote_mac,
                                    dst=self.pg0.local_mac) /
                              IP(dst="1.1.1.1", src="20.0.0.1") /
                              UDP(sport=1234, dport=1234 + ii) /
                              Raw(b'\xa5' * 100)))
            src_pkts.append((Ether(src=self.pg0.remote_mac,
                                   dst=self.pg0.local_mac) /
                             IP(dst="1.1.1.1", src="20.0.0.%d" % ii) /
                             UDP(sport=1234, dport=1234) /
                             Raw(b'\xa5' * 100)))

        route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
                                    [VppRoutePath(self.pg3.remote_ip4,
                                                  self.pg3.sw_if_index),
                                     VppRoutePath(self.pg4.remote_ip4,
                                                  self.pg4.sw_if_index)])
        route_10_0_0_2.add_vpp_config()

        route_1_1_1_1 = VppIpRoute(self, "1.1.1.1", 32,
                                   [VppRoutePath("10.0.0.2", 0xffffffff),
                                    VppRoutePath("10.0.0.1", 0xffffffff)])
        route_1_1_1_1.add_vpp_config()

        #
        # inject the packet on pg0 - expect load-balancing across all 4 paths
        #
        self.vapi.cli("clear trace")
        self.send_and_expect_load_balancing(self.pg0, port_pkts,
                                            [self.pg1, self.pg2,
                                             self.pg3, self.pg4])
        self.send_and_expect_load_balancing(self.pg0, src_pkts,
                                            [self.pg1, self.pg2,
                                             self.pg3, self.pg4])

        #
        # bring down pg1 expect LB to adjust to use only those that are up
        #
        self.pg1.link_down()

        rx = self.send_and_expect_load_balancing(self.pg0, src_pkts,
                                                 [self.pg2, self.pg3,
                                                  self.pg4])
        self.assertEqual(len(src_pkts), self.total_len(rx))

        #
        # bring down pg2 expect LB to adjust to use only those that are up
        #
        self.pg2.link_down()

        rx = self.send_and_expect_load_balancing(self.pg0, src_pkts,
                                                 [self.pg3, self.pg4])
        self.assertEqual(len(src_pkts), self.total_len(rx))

        #
        # bring the links back up - expect LB over all again
        #
        self.pg1.link_up()
        self.pg2.link_up()

        rx = self.send_and_expect_load_balancing(self.pg0, src_pkts,
                                                 [self.pg1, self.pg2,
                                                  self.pg3, self.pg4])
        self.assertEqual(len(src_pkts), self.total_len(rx))

        #
        # The same link-up/down but this time admin state
        #
        self.pg1.admin_down()
        self.pg2.admin_down()
        rx = self.send_and_expect_load_balancing(self.pg0, src_pkts,
                                                 [self.pg3, self.pg4])
        self.assertEqual(len(src_pkts), self.total_len(rx))
        self.pg1.admin_up()
        self.pg2.admin_up()
        self.pg1.resolve_arp()
        self.pg2.resolve_arp()
        rx = self.send_and_expect_load_balancing(self.pg0, src_pkts,
                                                 [self.pg1, self.pg2,
                                                  self.pg3, self.pg4])
        self.assertEqual(len(src_pkts), self.total_len(rx))

        #
        # Recursive prefixes
        #  - testing that 2 stages of load-balancing, no choices
        #
        port_pkts = []

        for ii in range(257):
            port_pkts.append((Ether(src=self.pg0.remote_mac,
                                    dst=self.pg0.local_mac) /
                              IP(dst="1.1.1.2", src="20.0.0.2") /
                              UDP(sport=1234, dport=1234 + ii) /
                              Raw(b'\xa5' * 100)))

        route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
                                    [VppRoutePath(self.pg3.remote_ip4,
                                                  self.pg3.sw_if_index)])
        route_10_0_0_3.add_vpp_config()

        route_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32,
                                   [VppRoutePath("10.0.0.3", 0xffffffff)])
        route_1_1_1_2.add_vpp_config()

        #
        # inject the packet on pg0 - rx only on via routes output interface
        #
        self.vapi.cli("clear trace")
        self.send_and_expect_only(self.pg0, port_pkts, self.pg3)

        #
        # Add a LB route in the presence of a down link - expect no
        # packets over the down link
        #
        self.pg3.link_down()

        route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
                                    [VppRoutePath(self.pg3.remote_ip4,
                                                  self.pg3.sw_if_index),
                                     VppRoutePath(self.pg4.remote_ip4,
                                                  self.pg4.sw_if_index)])
        route_10_0_0_3.add_vpp_config()

        port_pkts = []
        for ii in range(257):
            port_pkts.append(Ether(src=self.pg0.remote_mac,
                                   dst=self.pg0.local_mac) /
                             IP(dst="10.0.0.3", src="20.0.0.2") /
                             UDP(sport=1234, dport=1234 + ii) /
                             Raw(b'\xa5' * 100))

        self.send_and_expect_only(self.pg0, port_pkts, self.pg4)

        # bring the link back up
        self.pg3.link_up()

        rx = self.send_and_expect_load_balancing(self.pg0, port_pkts,
                                                 [self.pg3, self.pg4])
        self.assertEqual(len(src_pkts), self.total_len(rx))


class TestIPVlan0(VppTestCase):
    """ IPv4 VLAN-0 """

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

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

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

        self.create_pg_interfaces(range(2))
        mpls_tbl = VppMplsTable(self, 0)
        mpls_tbl.add_vpp_config()

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

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

    def test_ip_vlan_0(self):
        """ IP VLAN-0 """

        pkts = (Ether(src=self.pg0.remote_mac,
                      dst=self.pg0.local_mac) /
                Dot1Q(vlan=0) /
                IP(dst=self.pg1.remote_ip4,
                   src=self.pg0.remote_ip4) /
                UDP(sport=1234, dport=1234) /
                Raw(b'\xa5' * 100)) * NUM_PKTS

        #
        # Expect that packets sent on VLAN-0 are forwarded on the
        # main interface.
        #
        self.send_and_expect(self.pg0, pkts, self.pg1)


class IPPuntSetup(object):
    """ Setup for IPv4 Punt Police/Redirect """

    def punt_setup(self):
        self.create_pg_interfaces(range(4))

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

        # use UDP packet that have a port we need to explicitly
        # register to get punted.
        pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
        af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
        udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
        punt_udp = {
            'type': pt_l4,
            'punt': {
                'l4': {
                    'af': af_ip4,
                    'protocol': udp_proto,
                    'port': 1234,
                }
            }
        }

        self.vapi.set_punt(is_add=1, punt=punt_udp)

        af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
        punt_udp = {
            'type': pt_l4,
            'punt': {
                'l4': {
                    'af': af_ip6,
                    'protocol': udp_proto,
                    'port': 1236,
                }
            }
        }

        self.vapi.set_punt(is_add=1, punt=punt_udp)

        self.pkt = (Ether(src=self.pg0.remote_mac,
                          dst=self.pg0.local_mac) /
                    IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
                    UDP(sport=1234, dport=1234) /
                    Raw(b'\xa5' * 100))

    def punt_teardown(self):
        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.admin_down()


class TestIPPunt(IPPuntSetup, VppTestCase):
    """ IPv4 Punt Police/Redirect """

    def setUp(self):
        super().setUp()
        super().punt_setup()

    def tearDown(self):
        super().punt_teardown()
        super().tearDown()

    def test_ip_punt_api_validation(self):
        """ IP punt API parameter validation """

        nh_addr = self.pg1.remote_ip4
        punt = {"rx_sw_if_index": self.pg0.sw_if_index,
                "af": VppEnum.vl_api_address_family_t.ADDRESS_IP4,
                "n_paths": 1000000,
                "paths": []}

        with self.assertRaises(vpp_papi.VPPIOError):
            self.vapi.add_del_ip_punt_redirect_v2(punt=punt, is_add=True)

        punt = {"rx_sw_if_index": self.pg0.sw_if_index,
                "af": VppEnum.vl_api_address_family_t.ADDRESS_IP4,
                "n_paths": 0,
                "paths": []}

        self.vapi.add_del_ip_punt_redirect_v2(punt=punt, is_add=True)

    def test_ip_punt(self):
        """ IP punt police and redirect """

        pkts = self.pkt * 1025

        #
        # Configure a punt redirect via pg1.
        #
        nh_addr = self.pg1.remote_ip4
        ip_punt_redirect = VppIpPuntRedirect(self, self.pg0.sw_if_index,
                                             self.pg1.sw_if_index, nh_addr)
        ip_punt_redirect.add_vpp_config()

        self.send_and_expect(self.pg0, pkts, self.pg1)

        #
        # add a policer
        #
        policer = VppPolicer(self, "ip4-punt", 400, 0, 10, 0, rate_type=1)
        policer.add_vpp_config()
        ip_punt_policer = VppIpPuntPolicer(self, policer.policer_index)
        ip_punt_policer.add_vpp_config()

        self.vapi.cli("clear trace")
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        #
        # the number of packet received should be greater than 0,
        # but not equal to the number sent, since some were policed
        #
        rx = self.pg1._get_capture(1)

        stats = policer.get_stats()

        # Single rate policer - expect conform, violate but no exceed
        self.assertGreater(stats['conform_packets'], 0)
        self.assertEqual(stats['exceed_packets'], 0)
        self.assertGreater(stats['violate_packets'], 0)

        self.assertGreater(len(rx), 0)
        self.assertLess(len(rx), len(pkts))

        #
        # remove the policer. back to full rx
        #
        ip_punt_policer.remove_vpp_config()
        policer.remove_vpp_config()
        self.send_and_expect(self.pg0, pkts, self.pg1)

        #
        # remove the redirect. expect full drop.
        #
        ip_punt_redirect.remove_vpp_config()
        self.send_and_assert_no_replies(self.pg0, pkts,
                                        "IP no punt config")

        #
        # Add a redirect that is not input port selective
        #
        ip_punt_redirect = VppIpPuntRedirect(self, 0xffffffff,
                                             self.pg1.sw_if_index, nh_addr)
        ip_punt_redirect.add_vpp_config()
        self.send_and_expect(self.pg0, pkts, self.pg1)
        ip_punt_redirect.remove_vpp_config()

    def test_ip_punt_vrf(self):
        """ IP punt/local with VRFs """

        # use a punt redirect to test if for-us  packets are accepted
        pkts = self.pkt * 1025

        vlans_pg0 = [VppDot1QSubint(self, self.pg0, v)
                     for v in range(100, 104)]
        vlans_pg1 = [VppDot1QSubint(self, self.pg1, v)
                     for v in range(100, 104)]
        tbl4 = [VppIpTable(self, v).add_vpp_config()
                for v in range(100, 104)]
        tbl6 = [VppIpTable(self, v, True).add_vpp_config()
                for v in range(100, 104)]

        for v in vlans_pg0 + vlans_pg1:
            v.admin_up()
            v.set_table_ip4(v.vlan)
            v.set_table_ip6(v.vlan)
            v.config_ip4()
            v.config_ip6()
            v.resolve_arp()
            v.resolve_ndp()

        [VppIpPuntRedirect
         (self,
          vlans_pg0[i].sw_if_index,
          vlans_pg1[i].sw_if_index,
          vlans_pg1[i].remote_ip4).add_vpp_config()
         for i in range(4)]
        [VppIpPuntRedirect
         (self,
          vlans_pg0[i].sw_if_index,
          vlans_pg1[i].sw_if_index,
          vlans_pg1[i].remote_ip6).add_vpp_config()
         for i in range(4)]

        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IP(src=i.remote_ip4,
                    dst=i.local_ip4) /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]

        self.send_and_expect(self.pg0, pkts, self.pg1)

        #
        # IPv4
        #

        # we reject packets for source addresses in the wrong vlan/VRF
        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IP(src="1.1.1.1",
                    dst=i.local_ip4) /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]
        # single and dual loop
        self.send_and_assert_no_replies(self.pg0, [pkts[0]])
        self.send_and_assert_no_replies(self.pg0, pkts)

        self.assert_error_counter_equal(
            "/err/ip4-local/ip4 source lookup miss",
            len(pkts) + 1)

        # using the same source in different tables, should reject
        # for the table that the source is not present in
        # the first packet in the stream is drop
        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IP(src=vlans_pg0[0].remote_ip4,
                    dst=i.local_ip4) /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]
        # single loop accept and drop
        # followed by both in the same frame/loop
        self.send_and_expect(self.pg0, [pkts[0]], self.pg1)
        self.send_and_assert_no_replies(self.pg0, [pkts[1]])
        self.send_and_expect(self.pg0, pkts * 4, self.pg1, n_rx=4)

        # using the same source in different tables, should reject
        # for the table that the source is not present in
        # the first packet in the stream is accept
        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IP(src=vlans_pg0[3].remote_ip4,
                    dst=i.local_ip4) /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]

        # single loop accept and drop
        # followed by both in the same frame/loop
        self.send_and_expect(self.pg0, [pkts[3]], self.pg1)
        self.send_and_assert_no_replies(self.pg0, [pkts[1]])
        self.send_and_expect(self.pg0, pkts * 4, self.pg1, n_rx=4)

        #
        # IPv6
        #

        # we reject packets for source addresses in the wrong vlan/VRF
        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IPv6(src="1::1",
                      dst=i.local_ip6) /
                 UDP(sport=1236, dport=1236) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]
        # single and dual loop
        self.send_and_assert_no_replies(self.pg0, [pkts[0]])
        self.send_and_assert_no_replies(self.pg0, pkts)

        self.assert_error_counter_equal(
            "/err/ip6-input/ip6 source lookup miss",
            len(pkts) + 1)

        # using the same source in different tables, should reject
        # for the table that the source is not present in
        # the first packet in the stream is drop
        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IPv6(src=vlans_pg0[0].remote_ip6,
                      dst=i.local_ip6) /
                 UDP(sport=1236, dport=1236) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]
        # single loop accept and drop
        # followed by both in the same frame/loop
        self.send_and_expect(self.pg0, [pkts[0]], self.pg1)
        self.send_and_assert_no_replies(self.pg0, [pkts[1]])
        self.send_and_expect(self.pg0, pkts * 4, self.pg1, n_rx=4)

        # using the same source in different tables, should reject
        # for the table that the source is not present in
        # the first packet in the stream is accept
        pkts = [(Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 Dot1Q(vlan=i.vlan) /
                 IPv6(src=vlans_pg0[3].remote_ip6,
                      dst=i.local_ip6) /
                 UDP(sport=1236, dport=1236) /
                 Raw(b'\xa5' * 100))
                for i in vlans_pg0]

        # single loop accept and drop
        # followed by both in the same frame/loop
        self.send_and_expect(self.pg0, [pkts[3]], self.pg1)
        self.send_and_assert_no_replies(self.pg0, [pkts[1]])
        self.send_and_expect(self.pg0, pkts * 4, self.pg1, n_rx=4)

        for v in vlans_pg0 + vlans_pg1:
            v.unconfig_ip4()
            v.unconfig_ip6()
            v.set_table_ip4(0)
            v.set_table_ip6(0)

    def test_ip_punt_dump(self):
        """ IP4 punt redirect dump"""

        #
        # Configure a punt redirects
        #
        nh_address = self.pg3.remote_ip4
        ipr_03 = VppIpPuntRedirect(self, self.pg0.sw_if_index,
                                   self.pg3.sw_if_index, nh_address)
        ipr_13 = VppIpPuntRedirect(self, self.pg1.sw_if_index,
                                   self.pg3.sw_if_index, nh_address)
        ipr_23 = VppIpPuntRedirect(self, self.pg2.sw_if_index,
                                   self.pg3.sw_if_index, "0.0.0.0")
        ipr_03.add_vpp_config()
        ipr_13.add_vpp_config()
        ipr_23.add_vpp_config()

        #
        # Dump pg0 punt redirects
        #
        self.assertTrue(ipr_03.query_vpp_config())
        self.assertTrue(ipr_13.query_vpp_config())
        self.assertTrue(ipr_23.query_vpp_config())

        #
        # Dump punt redirects for all interfaces
        #
        punts = self.vapi.ip_punt_redirect_dump(0xffffffff)
        self.assertEqual(len(punts), 3)
        for p in punts:
            self.assertEqual(p.punt.tx_sw_if_index, self.pg3.sw_if_index)
        self.assertNotEqual(punts[1].punt.nh, self.pg3.remote_ip4)
        self.assertEqual(str(punts[2].punt.nh), '0.0.0.0')


class TestIPPuntHandoff(IPPuntSetup, VppTestCase):
    """ IPv4 Punt Policer thread handoff """
    vpp_worker_count = 2

    def setUp(self):
        super(TestIPPuntHandoff, self).setUp()
        super(TestIPPuntHandoff, self).punt_setup()

    def tearDown(self):
        super(TestIPPuntHandoff, self).punt_teardown()
        super(TestIPPuntHandoff, self).tearDown()

    def test_ip_punt_policer_handoff(self):
        """ IP4 punt policer thread handoff """
        pkts = self.pkt * NUM_PKTS

        #
        # Configure a punt redirect via pg1.
        #
        nh_addr = self.pg1.remote_ip4
        ip_punt_redirect = VppIpPuntRedirect(self, self.pg0.sw_if_index,
                                             self.pg1.sw_if_index, nh_addr)
        ip_punt_redirect.add_vpp_config()

        action_tx = PolicerAction(
            VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT,
            0)
        #
        # This policer drops no packets, we are just
        # testing that they get to the right thread.
        #
        policer = VppPolicer(self, "ip4-punt", 400, 0, 10, 0, 1,
                             0, 0, False, action_tx, action_tx, action_tx)
        policer.add_vpp_config()
        ip_punt_policer = VppIpPuntPolicer(self, policer.policer_index)
        ip_punt_policer.add_vpp_config()

        for worker in [0, 1]:
            self.send_and_expect(self.pg0, pkts, self.pg1, worker=worker)
            self.logger.debug(self.vapi.cli("show trace max 100"))

        # Combined stats, all threads
        stats = policer.get_stats()

        # Single rate policer - expect conform, violate but no exceed
        self.assertGreater(stats['conform_packets'], 0)
        self.assertEqual(stats['exceed_packets'], 0)
        self.assertGreater(stats['violate_packets'], 0)

        # Worker 0, should have done all the policing
        stats0 = policer.get_stats(worker=0)
        self.assertEqual(stats, stats0)

        # Worker 1, should have handed everything off
        stats1 = policer.get_stats(worker=1)
        self.assertEqual(stats1['conform_packets'], 0)
        self.assertEqual(stats1['exceed_packets'], 0)
        self.assertEqual(stats1['violate_packets'], 0)

        # Bind the policer to worker 1 and repeat
        policer.bind_vpp_config(1, True)
        for worker in [0, 1]:
            self.send_and_expect(self.pg0, pkts, self.pg1, worker=worker)
            self.logger.debug(self.vapi.cli("show trace max 100"))

        # The 2 workers should now have policed the same amount
        stats = policer.get_stats()
        stats0 = policer.get_stats(worker=0)
        stats1 = policer.get_stats(worker=1)

        self.assertGreater(stats0['conform_packets'], 0)
        self.assertEqual(stats0['exceed_packets'], 0)
        self.assertGreater(stats0['violate_packets'], 0)

        self.assertGreater(stats1['conform_packets'], 0)
        self.assertEqual(stats1['exceed_packets'], 0)
        self.assertGreater(stats1['violate_packets'], 0)

        self.assertEqual(stats0['conform_packets'] + stats1['conform_packets'],
                         stats['conform_packets'])

        self.assertEqual(stats0['violate_packets'] + stats1['violate_packets'],
                         stats['violate_packets'])

        # Unbind the policer and repeat
        policer.bind_vpp_config(1, False)
        for worker in [0, 1]:
            self.send_and_expect(self.pg0, pkts, self.pg1, worker=worker)
            self.logger.debug(self.vapi.cli("show trace max 100"))

        # The policer should auto-bind to worker 0 when packets arrive
        stats = policer.get_stats()
        stats0new = policer.get_stats(worker=0)
        stats1new = policer.get_stats(worker=1)

        self.assertGreater(stats0new['conform_packets'],
                           stats0['conform_packets'])
        self.assertEqual(stats0new['exceed_packets'], 0)
        self.assertGreater(stats0new['violate_packets'],
                           stats0['violate_packets'])

        self.assertEqual(stats1, stats1new)

        #
        # Clean up
        #
        ip_punt_policer.remove_vpp_config()
        policer.remove_vpp_config()
        ip_punt_redirect.remove_vpp_config()


class TestIPDeag(VppTestCase):
    """ IPv4 Deaggregate Routes """

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

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

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

        self.create_pg_interfaces(range(3))

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

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

    def test_ip_deag(self):
        """ IP Deag Routes """

        #
        # Create a table to be used for:
        #  1 - another destination address lookup
        #  2 - a source address lookup
        #
        table_dst = VppIpTable(self, 1)
        table_src = VppIpTable(self, 2)
        table_dst.add_vpp_config()
        table_src.add_vpp_config()

        #
        # Add a route in the default table to point to a deag/
        # second lookup in each of these tables
        #
        route_to_dst = VppIpRoute(self, "1.1.1.1", 32,
                                  [VppRoutePath("0.0.0.0",
                                                0xffffffff,
                                                nh_table_id=1)])
        route_to_src = VppIpRoute(
            self, "1.1.1.2", 32,
            [VppRoutePath("0.0.0.0",
                          0xffffffff,
                          nh_table_id=2,
                          type=FibPathType.FIB_PATH_TYPE_SOURCE_LOOKUP)])
        route_to_dst.add_vpp_config()
        route_to_src.add_vpp_config()

        #
        # packets to these destination are dropped, since they'll
        # hit the respective default routes in the second table
        #
        p_dst = (Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 IP(src="5.5.5.5", dst="1.1.1.1") /
                 TCP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))
        p_src = (Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 IP(src="2.2.2.2", dst="1.1.1.2") /
                 TCP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))
        pkts_dst = p_dst * 257
        pkts_src = p_src * 257

        self.send_and_assert_no_replies(self.pg0, pkts_dst,
                                        "IP in dst table")
        self.send_and_assert_no_replies(self.pg0, pkts_src,
                                        "IP in src table")

        #
        # add a route in the dst table to forward via pg1
        #
        route_in_dst = VppIpRoute(self, "1.1.1.1", 32,
                                  [VppRoutePath(self.pg1.remote_ip4,
                                                self.pg1.sw_if_index)],
                                  table_id=1)
        route_in_dst.add_vpp_config()

        self.send_and_expect(self.pg0, pkts_dst, self.pg1)

        #
        # add a route in the src table to forward via pg2
        #
        route_in_src = VppIpRoute(self, "2.2.2.2", 32,
                                  [VppRoutePath(self.pg2.remote_ip4,
                                                self.pg2.sw_if_index)],
                                  table_id=2)
        route_in_src.add_vpp_config()
        self.send_and_expect(self.pg0, pkts_src, self.pg2)

        #
        # loop in the lookup DP
        #
        route_loop = VppIpRoute(self, "2.2.2.3", 32,
                                [VppRoutePath("0.0.0.0",
                                              0xffffffff,
                                              nh_table_id=0)])
        route_loop.add_vpp_config()

        p_l = (Ether(src=self.pg0.remote_mac,
                     dst=self.pg0.local_mac) /
               IP(src="2.2.2.4", dst="2.2.2.3") /
               TCP(sport=1234, dport=1234) /
               Raw(b'\xa5' * 100))

        self.send_and_assert_no_replies(self.pg0, p_l * 257,
                                        "IP lookup loop")


class TestIPInput(VppTestCase):
    """ IPv4 Input Exceptions """

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

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

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

        self.create_pg_interfaces(range(2))

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

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

    def test_ip_input(self):
        """ IP Input Exceptions """

        # i can't find a way in scapy to construct an IP packet
        # with a length less than the IP header length

        #
        # Packet too short - this is forwarded
        #
        p_short = (Ether(src=self.pg0.remote_mac,
                         dst=self.pg0.local_mac) /
                   IP(src=self.pg0.remote_ip4,
                      dst=self.pg1.remote_ip4,
                      len=40) /
                   UDP(sport=1234, dport=1234) /
                   Raw(b'\xa5' * 100))

        rx = self.send_and_expect(self.pg0, p_short * NUM_PKTS, self.pg1)

        #
        # Packet too long - this is dropped
        #
        p_long = (Ether(src=self.pg0.remote_mac,
                        dst=self.pg0.local_mac) /
                  IP(src=self.pg0.remote_ip4,
                     dst=self.pg1.remote_ip4,
                     len=400) /
                  UDP(sport=1234, dport=1234) /
                  Raw(b'\xa5' * 100))

        rx = self.send_and_assert_no_replies(self.pg0, p_long * NUM_PKTS,
                                             "too long")

        #
        # bad chksum - this is dropped
        #
        p_chksum = (Ether(src=self.pg0.remote_mac,
                          dst=self.pg0.local_mac) /
                    IP(src=self.pg0.remote_ip4,
                       dst=self.pg1.remote_ip4,
                       chksum=400) /
                    UDP(sport=1234, dport=1234) /
                    Raw(b'\xa5' * 100))

        rx = self.send_and_assert_no_replies(self.pg0, p_chksum * NUM_PKTS,
                                             "bad checksum")

        #
        # bad version - this is dropped
        #
        p_ver = (Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 IP(src=self.pg0.remote_ip4,
                    dst=self.pg1.remote_ip4,
                    version=3) /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))

        rx = self.send_and_assert_no_replies(self.pg0, p_ver * NUM_PKTS,
                                             "funky version")

        #
        # fragment offset 1 - this is dropped
        #
        p_frag = (Ether(src=self.pg0.remote_mac,
                        dst=self.pg0.local_mac) /
                  IP(src=self.pg0.remote_ip4,
                     dst=self.pg1.remote_ip4,
                     frag=1) /
                  UDP(sport=1234, dport=1234) /
                  Raw(b'\xa5' * 100))

        rx = self.send_and_assert_no_replies(self.pg0, p_frag * NUM_PKTS,
                                             "frag offset")

        #
        # TTL expired packet
        #
        p_ttl = (Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 IP(src=self.pg0.remote_ip4,
                    dst=self.pg1.remote_ip4,
                    ttl=1) /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 100))

        rxs = self.send_and_expect_some(self.pg0, p_ttl * NUM_PKTS, self.pg0)

        for rx in rxs:
            icmp = rx[ICMP]
            self.assertEqual(icmptypes[icmp.type], "time-exceeded")
            self.assertEqual(icmpcodes[icmp.type][icmp.code],
                             "ttl-zero-during-transit")
            self.assertEqual(icmp.src, self.pg0.remote_ip4)
            self.assertEqual(icmp.dst, self.pg1.remote_ip4)

        #
        # MTU exceeded
        #
        p_mtu = (Ether(src=self.pg0.remote_mac,
                       dst=self.pg0.local_mac) /
                 IP(src=self.pg0.remote_ip4,
                    dst=self.pg1.remote_ip4,
                    ttl=10, flags='DF') /
                 UDP(sport=1234, dport=1234) /
                 Raw(b'\xa5' * 2000))

        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1500, 0, 0, 0])

        rxs = self.send_and_expect_some(self.pg0, p_mtu * NUM_PKTS, self.pg0)

        for rx in rxs:
            icmp = rx[ICMP]
            self.assertEqual(icmptypes[icmp.type], "dest-unreach")
            self.assertEqual(icmpcodes[icmp.type][icmp.code],
                             "fragmentation-needed")
            self.assertEqual(icmp.nexthopmtu, 1500)
            self.assertEqual(icmp.src, self.pg0.remote_ip4)
            self.assertEqual(icmp.dst, self.pg1.remote_ip4)

        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [2500, 0, 0, 0])
        rx = self.send_and_expect(self.pg0, p_mtu * NUM_PKTS, self.pg1)

        # Reset MTU for subsequent tests
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])

        #
        # source address 0.0.0.0 and 25.255.255.255 and for-us
        #
        p_s0 = (Ether(src=self.pg0.remote_mac,
                      dst=self.pg0.local_mac) /
                IP(src="0.0.0.0",
                   dst=self.pg0.local_ip4) /
                ICMP(id=4, seq=4) /
                Raw(load=b'\x0a' * 18))
        rx = self.send_and_assert_no_replies(self.pg0, p_s0 * 17)

        p_s0 = (Ether(src=self.pg0.remote_mac,
                      dst=self.pg0.local_mac) /
                IP(src="255.255.255.255",
                   dst=self.pg0.local_ip4) /
                ICMP(id=4, seq=4) /
                Raw(load=b'\x0a' * 18))
        rx = self.send_and_assert_no_replies(self.pg0, p_s0 * 17)


class TestIPDirectedBroadcast(VppTestCase):
    """ IPv4 Directed Broadcast """

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

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

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

        self.create_pg_interfaces(range(2))

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

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

    def test_ip_input(self):
        """ IP Directed Broadcast """

        #
        # set the directed broadcast on pg0 first, then config IP4 addresses
        # for pg1 directed broadcast is always disabled
        self.vapi.sw_interface_set_ip_directed_broadcast(
            self.pg0.sw_if_index, 1)

        p0 = (Ether(src=self.pg1.remote_mac,
                    dst=self.pg1.local_mac) /
              IP(src="1.1.1.1",
                 dst=self.pg0._local_ip4_bcast) /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 2000))
        p1 = (Ether(src=self.pg0.remote_mac,
                    dst=self.pg0.local_mac) /
              IP(src="1.1.1.1",
                 dst=self.pg1._local_ip4_bcast) /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 2000))

        self.pg0.config_ip4()
        self.pg0.resolve_arp()
        self.pg1.config_ip4()
        self.pg1.resolve_arp()

        #
        # test packet is L2 broadcast
        #
        rx = self.send_and_expect(self.pg1, p0 * NUM_PKTS, self.pg0)
        self.assertTrue(rx[0][Ether].dst, "ff:ff:ff:ff:ff:ff")

        self.send_and_assert_no_replies(self.pg0, p1 * NUM_PKTS,
                                        "directed broadcast disabled")

        #
        # toggle directed broadcast on pg0
        #
        self.vapi.sw_interface_set_ip_directed_broadcast(
            self.pg0.sw_if_index, 0)
        self.send_and_assert_no_replies(self.pg1, p0 * NUM_PKTS,
                                        "directed broadcast disabled")

        self.vapi.sw_interface_set_ip_directed_broadcast(
            self.pg0.sw_if_index, 1)
        rx = self.send_and_expect(self.pg1, p0 * NUM_PKTS, self.pg0)

        self.pg0.unconfig_ip4()
        self.pg1.unconfig_ip4()


class TestIPLPM(VppTestCase):
    """ IPv4 longest Prefix Match """

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

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

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

        self.create_pg_interfaces(range(4))

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

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

    def test_ip_lpm(self):
        """ IP longest Prefix Match """

        s_24 = VppIpRoute(self, "10.1.2.0", 24,
                          [VppRoutePath(self.pg1.remote_ip4,
                                        self.pg1.sw_if_index)])
        s_24.add_vpp_config()
        s_8 = VppIpRoute(self, "10.0.0.0", 8,
                         [VppRoutePath(self.pg2.remote_ip4,
                                       self.pg2.sw_if_index)])
        s_8.add_vpp_config()

        p_8 = (Ether(src=self.pg0.remote_mac,
                     dst=self.pg0.local_mac) /
               IP(src="1.1.1.1",
                  dst="10.1.1.1") /
               UDP(sport=1234, dport=1234) /
               Raw(b'\xa5' * 2000))
        p_24 = (Ether(src=self.pg0.remote_mac,
                      dst=self.pg0.local_mac) /
                IP(src="1.1.1.1",
                   dst="10.1.2.1") /
                UDP(sport=1234, dport=1234) /
                Raw(b'\xa5' * 2000))

        self.logger.info(self.vapi.cli("sh ip fib mtrie"))
        rx = self.send_and_expect(self.pg0, p_8 * NUM_PKTS, self.pg2)
        rx = self.send_and_expect(self.pg0, p_24 * NUM_PKTS, self.pg1)


@tag_fixme_vpp_workers
class TestIPv4Frag(VppTestCase):
    """ IPv4 fragmentation """

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

        cls.create_pg_interfaces([0, 1])
        cls.src_if = cls.pg0
        cls.dst_if = cls.pg1

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

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

    def test_frag_large_packets(self):
        """ Fragmentation of large packets """

        self.vapi.cli("adjacency counters enable")

        p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4) /
             UDP(sport=1234, dport=5678) / Raw())
        self.extend_packet(p, 6000, "abcde")
        saved_payload = p[Raw].load

        nbr = VppNeighbor(self,
                          self.dst_if.sw_if_index,
                          self.dst_if.remote_mac,
                          self.dst_if.remote_ip4).add_vpp_config()

        # Force fragmentation by setting MTU of output interface
        # lower than packet size
        self.vapi.sw_interface_set_mtu(self.dst_if.sw_if_index,
                                       [5000, 0, 0, 0])

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

        # Expecting 3 fragments because size of created fragments currently
        # cannot be larger then VPP buffer size (which is 2048)
        packets = self.dst_if.get_capture(3)

        # we should show 3 packets thru the neighbor
        self.assertEqual(3, nbr.get_stats()['packets'])

        # Assume VPP sends the fragments in order
        payload = b''
        for p in packets:
            payload_offset = p.frag * 8
            if payload_offset > 0:
                payload_offset -= 8  # UDP header is not in payload
            self.assert_equal(payload_offset, len(payload))
            payload += p[Raw].load
        self.assert_equal(payload, saved_payload, "payload")


class TestIPReplace(VppTestCase):
    """ IPv4 Table Replace """

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

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

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

        self.create_pg_interfaces(range(4))

        table_id = 1
        self.tables = []

        for i in self.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()
            i.generate_remote_hosts(2)
            self.tables.append(VppIpTable(self, table_id).add_vpp_config())
            table_id += 1

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

    def test_replace(self):
        """ IP Table Replace """

        MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
        MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
        N_ROUTES = 20
        links = [self.pg0, self.pg1, self.pg2, self.pg3]
        routes = [[], [], [], []]

        # load up the tables with some routes
        for ii, t in enumerate(self.tables):
            for jj in range(N_ROUTES):
                uni = VppIpRoute(
                    self, "10.0.0.%d" % jj, 32,
                    [VppRoutePath(links[ii].remote_hosts[0].ip4,
                                  links[ii].sw_if_index),
                     VppRoutePath(links[ii].remote_hosts[1].ip4,
                                  links[ii].sw_if_index)],
                    table_id=t.table_id).add_vpp_config()
                multi = VppIpMRoute(
                    self, "0.0.0.0",
                    "239.0.0.%d" % jj, 32,
                    MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
                    [VppMRoutePath(self.pg0.sw_if_index,
                                   MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
                     VppMRoutePath(self.pg1.sw_if_index,
                                   MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
                     VppMRoutePath(self.pg2.sw_if_index,
                                   MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
                     VppMRoutePath(self.pg3.sw_if_index,
                                   MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)],
                    table_id=t.table_id).add_vpp_config()
                routes[ii].append({'uni': uni,
                                   'multi': multi})

        #
        # replace the tables a few times
        #
        for kk in range(3):
            # replace_begin each table
            for t in self.tables:
                t.replace_begin()

            # all the routes are still there
            for ii, t in enumerate(self.tables):
                dump = t.dump()
                mdump = t.mdump()
                for r in routes[ii]:
                    self.assertTrue(find_route_in_dump(dump, r['uni'], t))
                    self.assertTrue(find_mroute_in_dump(mdump, r['multi'], t))

            # redownload the even numbered routes
            for ii, t in enumerate(self.tables):
                for jj in range(0, N_ROUTES, 2):
                    routes[ii][jj]['uni'].add_vpp_config()
                    routes[ii][jj]['multi'].add_vpp_config()

            # signal each table replace_end
            for t in self.tables:
                t.replace_end()

            # we should find the even routes, but not the odd
            for ii, t in enumerate(self.tables):
                dump = t.dump()
                mdump = t.mdump()
                for jj in range(0, N_ROUTES, 2):
                    self.assertTrue(find_route_in_dump(
                        dump, routes[ii][jj]['uni'], t))
                    self.assertTrue(find_mroute_in_dump(
                        mdump, routes[ii][jj]['multi'], t))
                for jj in range(1, N_ROUTES - 1, 2):
                    self.assertFalse(find_route_in_dump(
                        dump, routes[ii][jj]['uni'], t))
                    self.assertFalse(find_mroute_in_dump(
                        mdump, routes[ii][jj]['multi'], t))

            # reload all the routes
            for ii, t in enumerate(self.tables):
                for r in routes[ii]:
                    r['uni'].add_vpp_config()
                    r['multi'].add_vpp_config()

            # all the routes are still there
            for ii, t in enumerate(self.tables):
                dump = t.dump()
                mdump = t.mdump()
                for r in routes[ii]:
                    self.assertTrue(find_route_in_dump(dump, r['uni'], t))
                    self.assertTrue(find_mroute_in_dump(mdump, r['multi'], t))

        #
        # finally flush the tables for good measure
        #
        for t in self.tables:
            t.flush()
            self.assertEqual(len(t.dump()), 5)
            self.assertEqual(len(t.mdump()), 3)


class TestIPCover(VppTestCase):
    """ IPv4 Table Cover """

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

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

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

        self.create_pg_interfaces(range(4))

        table_id = 1
        self.tables = []

        for i in self.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()
            i.generate_remote_hosts(2)
            self.tables.append(VppIpTable(self, table_id).add_vpp_config())
            table_id += 1

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

    def test_cover(self):
        """ IP Table Cover """

        # add a loop back with a /32 prefix
        lo = VppLoInterface(self)
        lo.admin_up()
        a = VppIpInterfaceAddress(self, lo, "127.0.0.1", 32).add_vpp_config()

        # add a neighbour that matches the loopback's /32
        nbr = VppNeighbor(self,
                          lo.sw_if_index,
                          lo.remote_mac,
                          "127.0.0.1").add_vpp_config()

        # add the default route which will be the cover for /32
        r = VppIpRoute(self, "0.0.0.0", 0,
                       [VppRoutePath("127.0.0.1",
                                     lo.sw_if_index)],
                       register=False).add_vpp_config()

        # add/remove/add a longer mask cover
        r8 = VppIpRoute(self, "127.0.0.0", 8,
                        [VppRoutePath("127.0.0.1",
                                      lo.sw_if_index)]).add_vpp_config()
        r8.remove_vpp_config()
        r8.add_vpp_config()
        r8.remove_vpp_config()

        # remove the default route
        r.remove_vpp_config()

        # remove the interface prefix
        a.remove_vpp_config()


class TestIP4Replace(VppTestCase):
    """ IPv4 Interface Address Replace """

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

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

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

        self.create_pg_interfaces(range(4))

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

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

    def get_n_pfxs(self, intf):
        return len(self.vapi.ip_address_dump(intf.sw_if_index))

    def test_replace(self):
        """ IP interface address replace """

        intf_pfxs = [[], [], [], []]

        # add prefixes to each of the interfaces
        for i in range(len(self.pg_interfaces)):
            intf = self.pg_interfaces[i]

            # 172.16.x.1/24
            addr = "172.16.%d.1" % intf.sw_if_index
            a = VppIpInterfaceAddress(self, intf, addr, 24).add_vpp_config()
            intf_pfxs[i].append(a)

            # 172.16.x.2/24 - a different address in the same subnet as above
            addr = "172.16.%d.2" % intf.sw_if_index
            a = VppIpInterfaceAddress(self, intf, addr, 24).add_vpp_config()
            intf_pfxs[i].append(a)

            # 172.15.x.2/24 - a different address and subnet
            addr = "172.15.%d.2" % intf.sw_if_index
            a = VppIpInterfaceAddress(self, intf, addr, 24).add_vpp_config()
            intf_pfxs[i].append(a)

        # a dump should n_address in it
        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 3)

        #
        # remove all the address thru a replace
        #
        self.vapi.sw_interface_address_replace_begin()
        self.vapi.sw_interface_address_replace_end()
        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 0)

        #
        # add all the interface addresses back
        #
        for p in intf_pfxs:
            for v in p:
                v.add_vpp_config()
        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 3)

        #
        # replace again, but this time update/re-add the address on the first
        # two interfaces
        #
        self.vapi.sw_interface_address_replace_begin()

        for p in intf_pfxs[:2]:
            for v in p:
                v.add_vpp_config()

        self.vapi.sw_interface_address_replace_end()

        # on the first two the address still exist,
        # on the other two they do not
        for intf in self.pg_interfaces[:2]:
            self.assertEqual(self.get_n_pfxs(intf), 3)
        for p in intf_pfxs[:2]:
            for v in p:
                self.assertTrue(v.query_vpp_config())
        for intf in self.pg_interfaces[2:]:
            self.assertEqual(self.get_n_pfxs(intf), 0)

        #
        # add all the interface addresses back on the last two
        #
        for p in intf_pfxs[2:]:
            for v in p:
                v.add_vpp_config()
        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 3)

        #
        # replace again, this time add different prefixes on all the interfaces
        #
        self.vapi.sw_interface_address_replace_begin()

        pfxs = []
        for intf in self.pg_interfaces:
            # 172.18.x.1/24
            addr = "172.18.%d.1" % intf.sw_if_index
            pfxs.append(VppIpInterfaceAddress(self, intf, addr,
                                              24).add_vpp_config())

        self.vapi.sw_interface_address_replace_end()

        # only .18 should exist on each interface
        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 1)
        for pfx in pfxs:
            self.assertTrue(pfx.query_vpp_config())

        #
        # remove everything
        #
        self.vapi.sw_interface_address_replace_begin()
        self.vapi.sw_interface_address_replace_end()
        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 0)

        #
        # add prefixes to each interface. post-begin add the prefix from
        # interface X onto interface Y. this would normally be an error
        # since it would generate a 'duplicate address' warning. but in
        # this case, since what is newly downloaded is sane, it's ok
        #
        for intf in self.pg_interfaces:
            # 172.18.x.1/24
            addr = "172.18.%d.1" % intf.sw_if_index
            VppIpInterfaceAddress(self, intf, addr, 24).add_vpp_config()

        self.vapi.sw_interface_address_replace_begin()

        pfxs = []
        for intf in self.pg_interfaces:
            # 172.18.x.1/24
            addr = "172.18.%d.1" % (intf.sw_if_index + 1)
            pfxs.append(VppIpInterfaceAddress(self, intf,
                                              addr, 24).add_vpp_config())

        self.vapi.sw_interface_address_replace_end()

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

        for intf in self.pg_interfaces:
            self.assertEqual(self.get_n_pfxs(intf), 1)
        for pfx in pfxs:
            self.assertTrue(pfx.query_vpp_config())


class TestIPv4PathMTU(VppTestCase):
    """ IPv4 Path MTU """

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

        cls.create_pg_interfaces(range(2))

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

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

    def test_path_mtu(self):
        """ Path MTU """

        #
        # The goal here is not to test that fragmentation works correctly,
        # that's done elsewhere, the intent is to ensure that the Path MTU
        # settings are honoured.
        #
        self.vapi.cli("adjacency counters enable")

        # set the interface MTU to a reasonable value
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
                                       [1800, 0, 0, 0])

        self.pg1.generate_remote_hosts(4)

        p_2k = (Ether(dst=self.pg0.local_mac,
                      src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4,
                   dst=self.pg1.remote_ip4) /
                UDP(sport=1234, dport=5678) /
                Raw(b'0xa' * 640))
        p_1k = (Ether(dst=self.pg0.local_mac,
                      src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4,
                   dst=self.pg1.remote_ip4) /
                UDP(sport=1234, dport=5678) /
                Raw(b'0xa' * 320))

        nbr = VppNeighbor(self,
                          self.pg1.sw_if_index,
                          self.pg1.remote_mac,
                          self.pg1.remote_ip4).add_vpp_config()

        # this is now the interface MTU frags
        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=2)
        self.send_and_expect(self.pg0, [p_1k], self.pg1)

        # drop the path MTU for this neighbour to below the interface MTU
        # expect more frags
        pmtu = VppIpPathMtu(self, self.pg1.remote_ip4, 900).add_vpp_config()

        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
        self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)

        # print/format the adj delegate
        self.logger.info(self.vapi.cli("sh adj 5"))

        # increase the path MTU to more than the interface
        # expect to use the interface MTU
        pmtu.modify(8192)

        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=2)
        self.send_and_expect(self.pg0, [p_1k], self.pg1)

        # go back to an MTU from the path
        # wrap the call around mark-n-sweep to enusre updates clear stale
        self.vapi.ip_path_mtu_replace_begin()
        pmtu.modify(900)
        self.vapi.ip_path_mtu_replace_end()

        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
        self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)

        # raise the interface's MTU
        # should still use that of the path
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
                                       [2000, 0, 0, 0])
        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
        self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)

        # set path high and interface low
        pmtu.modify(2000)
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
                                       [900, 0, 0, 0])
        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
        self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)

        # remove the path MTU using the mark-n-sweep semantics
        self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index,
                                       [1800, 0, 0, 0])
        self.vapi.ip_path_mtu_replace_begin()
        self.vapi.ip_path_mtu_replace_end()

        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=2)
        self.send_and_expect(self.pg0, [p_1k], self.pg1)

        #
        # set path MTU for a neighbour that doesn't exist, yet
        #
        pmtu2 = VppIpPathMtu(self,
                             self.pg1.remote_hosts[2].ip4,
                             900).add_vpp_config()

        p_2k = (Ether(dst=self.pg0.local_mac,
                      src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4,
                   dst=self.pg1.remote_hosts[2].ip4) /
                UDP(sport=1234, dport=5678) /
                Raw(b'0xa' * 640))
        p_1k = (Ether(dst=self.pg0.local_mac,
                      src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4,
                   dst=self.pg1.remote_hosts[2].ip4) /
                UDP(sport=1234, dport=5678) /
                Raw(b'0xa' * 320))

        nbr2 = VppNeighbor(self,
                           self.pg1.sw_if_index,
                           self.pg1.remote_hosts[2].mac,
                           self.pg1.remote_hosts[2].ip4).add_vpp_config()

        # should frag to the path MTU
        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
        self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)

        # remove and re-add the neighbour
        nbr2.remove_vpp_config()
        nbr2.add_vpp_config()

        # should frag to the path MTU
        self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
        self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)

        #
        # set PMTUs for many peers
        #
        N_HOSTS = 16
        self.pg1.generate_remote_hosts(16)
        self.pg1.configure_ipv4_neighbors()

        for h in range(N_HOSTS):
            pmtu = VppIpPathMtu(self, self.pg1.remote_hosts[h].ip4, 900)
            pmtu.add_vpp_config()
            self.assertTrue(pmtu.query_vpp_config())

        self.logger.info(self.vapi.cli("sh ip pmtu"))
        dump = list(self.vapi.vpp.details_iter(self.vapi.ip_path_mtu_get))
        self.assertEqual(N_HOSTS, len(dump))

        for h in range(N_HOSTS):
            p_2k[IP].dst = self.pg1.remote_hosts[h].ip4
            p_1k[IP].dst = self.pg1.remote_hosts[h].ip4

            # should frag to the path MTU
            self.send_and_expect(self.pg0, [p_2k], self.pg1, n_rx=3)
            self.send_and_expect(self.pg0, [p_1k], self.pg1, n_rx=2)


class TestIPv4ItfRebind(VppTestCase):
    """ IPv4 Interface Bind w/ attached routes """

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

        self.create_pg_interfaces(range(3))

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

    def test_rebind(self):
        """ Import to no import """

        TABLE_ID = 1
        tbl = VppIpTable(self, TABLE_ID).add_vpp_config()
        self.pg1.set_table_ip4(TABLE_ID)

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

        # add an attached route via an pg0
        # in a different table. this prefix should import
        rt = VppIpRoute(self, self.pg0.local_ip4, 24,
                        [VppRoutePath("0.0.0.0",
                                      self.pg0.sw_if_index)],
                        table_id=TABLE_ID).add_vpp_config()

        p = (Ether(dst=self.pg1.local_mac,
                   src=self.pg1.remote_mac) /
             IP(src=self.pg1.remote_ip4,
                dst=self.pg0.remote_ip4) /
             UDP(sport=1234, dport=5678) /
             Raw(b'0xa' * 640))

        rx = self.send_and_expect(self.pg1, [p], self.pg0)
        self.assertFalse(rx[0].haslayer(ARP))

        # then bind pg0 to a new table
        # so the prefix no longer imports
        self.pg0.unconfig_ip4()
        self.pg0.set_table_ip4(TABLE_ID)
        self.pg0.config_ip4()
        self.pg0.resolve_arp()

        rx = self.send_and_expect(self.pg1, [p], self.pg0)
        self.assertFalse(rx[0].haslayer(ARP))

        # revert back to imported
        self.pg0.unconfig_ip4()
        self.pg0.set_table_ip4(0)
        self.pg0.config_ip4()
        self.pg0.resolve_arp()

        rx = self.send_and_expect(self.pg1, [p], self.pg0)
        self.assertFalse(rx[0].haslayer(ARP))

        # cleanup
        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.set_table_ip4(0)
            i.admin_down()

        rt.remove_vpp_config()
        tbl.remove_vpp_config()

    def test_delete(self):
        """ Swap import tables """

        TABLE_ID1 = 1
        tbl1_4 = VppIpTable(self, TABLE_ID1).add_vpp_config()
        tbl1_6 = VppIpTable(self, TABLE_ID1, True).add_vpp_config()
        TABLE_ID2 = 2
        tbl2_4 = VppIpTable(self, TABLE_ID2).add_vpp_config()
        tbl2_6 = VppIpTable(self, TABLE_ID2, True).add_vpp_config()

        # table mappings
        self.pg1.set_table_ip4(TABLE_ID1)
        self.pg1.set_table_ip6(TABLE_ID1)
        self.pg2.set_table_ip4(TABLE_ID2)
        self.pg2.set_table_ip6(TABLE_ID2)

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

        # add an attached route in the default table via pg0
        # this should import to table 1
        rt4 = VppIpRoute(self, self.pg1.local_ip4, 24,
                         [VppRoutePath("0.0.0.0",
                                       self.pg1.sw_if_index)]).add_vpp_config()
        rt6 = VppIpRoute(self, self.pg1.local_ip6, 64,
                         [VppRoutePath("0.0.0.0",
                                       self.pg1.sw_if_index)]).add_vpp_config()

        p1 = (Ether(dst=self.pg0.local_mac,
                    src=self.pg0.remote_mac) /
              IP(src=self.pg1.remote_ip4,
                 dst=self.pg1.remote_ip4) /
              UDP(sport=1234, dport=5678) /
              Raw(b'0xa' * 640))

        # inject into table 0
        rx = self.send_and_expect(self.pg0, [p1], self.pg1)
        self.assertFalse(rx[0].haslayer(ARP))

        # swap the attached interface to table 2
        self.pg1.unconfig_ip4()
        self.pg1.unconfig_ip6()
        self.pg1.set_table_ip4(TABLE_ID2)
        self.pg1.set_table_ip6(TABLE_ID2)
        self.pg1.config_ip4()
        self.pg1.config_ip6()
        self.pg1.resolve_arp()

        # delete table 1
        tbl1_4.flush()
        tbl1_6.flush()
        tbl1_4.remove_vpp_config()
        tbl1_6.remove_vpp_config()

        rx = self.send_and_expect(self.pg0, [p1], self.pg1)
        self.assertFalse(rx[0].haslayer(ARP))

        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.unconfig_ip6()
            i.set_table_ip4(0)
            i.set_table_ip6(0)
            i.admin_down()


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