#!/usr/bin/env python3
import binascii
import random
import socket
import os
import threading
import struct
import copy
import fcntl
import time

from struct import unpack, unpack_from

try:
    import unittest2 as unittest
except ImportError:
    import unittest

from util import ppp, ppc
from re import compile
import scapy.compat
from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP, ICMP
from scapy.layers.ipsec import ESP
import scapy.layers.inet6 as inet6
from scapy.layers.inet6 import IPv6, ICMPv6DestUnreach
from scapy.contrib.ospf import OSPF_Hdr, OSPFv3_Hello
from framework import tag_fixme_vpp_workers
from framework import VppTestCase, VppTestRunner

from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect, VppIpsecInterface
from vpp_papi import VppEnum

NUM_PKTS = 67


class serverSocketThread(threading.Thread):
    """ Socket server thread"""

    def __init__(self, threadID, sockName):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.sockName = sockName
        self.sock = None
        self.rx_pkts = []
        self.stop_running = False

    def rx_packets(self):
        # Wait for some packets on socket
        while True:
            try:
                data = self.sock.recv(65536)

                # punt socket metadata
                # packet_desc = data[0:8]

                # Ethernet
                self.rx_pkts.append(Ether(data[8:]))
            except IOError as e:
                if e.errno == 11:
                    # nothing to receive, stop running or sleep a little
                    if self.stop_running:
                        break
                    time.sleep(0.1)
                    pass
                else:
                    raise

    def run(self):
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        try:
            os.unlink(self.sockName)
        except:
            pass
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
        fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
        self.sock.bind(self.sockName)

        self.rx_packets()

    def close(self):
        self.stop_running = True
        threading.Thread.join(self)
        self.sock.close()
        return self.rx_pkts


class TestPuntSocket(VppTestCase):
    """ Punt Socket """

    ports = [1111, 2222, 3333, 4444]
    sock_servers = list()
    # FIXME: nr_packets > 3 results in failure
    # nr_packets = 3 makes the test unstable
    nr_packets = 2

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

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

    @classmethod
    def setUpConstants(cls):
        cls.extra_vpp_punt_config = [
            "punt", "{", "socket", cls.tempdir+"/socket_punt", "}"]
        super(TestPuntSocket, cls).setUpConstants()

    def setUp(self):
        super(TestPuntSocket, self).setUp()
        random.seed()

        self.create_pg_interfaces(range(2))
        for i in self.pg_interfaces:
            i.admin_up()

    def tearDown(self):
        del self.sock_servers[:]
        super(TestPuntSocket, self).tearDown()

    def socket_client_create(self, sock_name, id=None):
        thread = serverSocketThread(id, sock_name)
        self.sock_servers.append(thread)
        thread.start()
        return thread

    def socket_client_close(self):
        rx_pkts = []
        for thread in self.sock_servers:
            rx_pkts += thread.close()
        return rx_pkts

    def verify_port(self, pr, vpr):
        self.assertEqual(vpr.punt.type, pr['type'])
        self.assertEqual(vpr.punt.punt.l4.port,
                         pr['punt']['l4']['port'])
        self.assertEqual(vpr.punt.punt.l4.protocol,
                         pr['punt']['l4']['protocol'])
        self.assertEqual(vpr.punt.punt.l4.af,
                         pr['punt']['l4']['af'])

    def verify_exception(self, pr, vpr):
        self.assertEqual(vpr.punt.type, pr['type'])
        self.assertEqual(vpr.punt.punt.exception.id,
                         pr['punt']['exception']['id'])

    def verify_ip_proto(self, pr, vpr):
        self.assertEqual(vpr.punt.type, pr['type'])
        self.assertEqual(vpr.punt.punt.ip_proto.af,
                         pr['punt']['ip_proto']['af'])
        self.assertEqual(vpr.punt.punt.ip_proto.protocol,
                         pr['punt']['ip_proto']['protocol'])

    def verify_udp_pkts(self, rxs, n_rx, port):
        n_match = 0
        for rx in rxs:
            self.assertTrue(rx.haslayer(UDP))
            if rx[UDP].dport == port:
                n_match += 1
        self.assertEqual(n_match, n_rx)


def set_port(pr, port):
    pr['punt']['l4']['port'] = port
    return pr


def set_reason(pr, reason):
    pr['punt']['exception']['id'] = reason
    return pr


def mk_vpp_cfg4():
    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_l4 = {
        'type': pt_l4,
        'punt': {
            'l4': {
                'af': af_ip4,
                'protocol': udp_proto
            }
        }
    }
    return punt_l4


def mk_vpp_cfg6():
    pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
    af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
    udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
    punt_l4 = {
        'type': pt_l4,
        'punt': {
            'l4': {
                'af': af_ip6,
                'protocol': udp_proto
            }
        }
    }
    return punt_l4


class TestIP4PuntSocket(TestPuntSocket):
    """ Punt Socket for IPv4 UDP """

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

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

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

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

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

    def test_punt_socket_dump(self):
        """ Punt socket registration/deregistration"""

        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

        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

        #
        # configure a punt socket
        #
        punt_l4 = mk_vpp_cfg4()

        self.vapi.punt_socket_register(set_port(punt_l4, 1111),
                                       "%s/socket_punt_1111" % self.tempdir)
        self.vapi.punt_socket_register(set_port(punt_l4, 2222),
                                       "%s/socket_punt_2222" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 2)
        self.verify_port(set_port(punt_l4, 1111), punts[0])
        self.verify_port(set_port(punt_l4, 2222), punts[1])

        #
        # deregister a punt socket
        #
        self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 1)

        #
        # configure a punt socket again
        #
        self.vapi.punt_socket_register(set_port(punt_l4, 1111),
                                       "%s/socket_punt_1111" % self.tempdir)
        self.vapi.punt_socket_register(set_port(punt_l4, 3333),
                                       "%s/socket_punt_3333" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 3)

        self.logger.info(self.vapi.cli("sh punt sock reg"))

        #
        # deregister all punt socket
        #
        self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
        self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
        self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

    def test_punt_socket_traffic_single_port_single_socket(self):
        """ Punt socket traffic single port single socket"""

        port = self.ports[0]
        pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
        punt_l4 = set_port(mk_vpp_cfg4(), port)

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

        pkts = p * self.nr_packets

        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

        #
        # expect ICMP - port unreachable for all packets
        #
        rx = self.send_and_expect(self.pg0, pkts, self.pg0)

        for p in rx:
            self.assertEqual(int(p[IP].proto), 1)   # ICMP
            self.assertEqual(int(p[ICMP].code), 3)  # unreachable

        #
        # configure a punt socket
        #
        self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
        self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" %
                                       (self.tempdir, port))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 1)

        #
        # expect punt socket and no packets on pg0
        #
        self.send_and_assert_no_replies(self.pg0, pkts)
        rx = self.socket_client_close()
        self.verify_udp_pkts(rx, len(pkts), port)

        #
        # remove punt socket. expect ICMP - port unreachable for all packets
        #
        self.vapi.punt_socket_deregister(punt_l4)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

        rx = self.send_and_expect(self.pg0, pkts, self.pg0)
        for p in rx:
            self.assertEqual(int(p[IP].proto), 1)   # ICMP
            self.assertEqual(int(p[ICMP].code), 3)  # unreachable

    def test_punt_socket_traffic_multi_ports_multi_sockets(self):
        """ Punt socket traffic multi ports and multi sockets"""

        punt_l4 = mk_vpp_cfg4()

        # configuration for each UDP port
        cfgs = dict()

        #
        # create stream of packets for each port
        #
        for port in self.ports:
            # choose port from port list
            cfgs[port] = {}

            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=9876, dport=port) /
                   Raw(b'\xa5' * 100))
            cfgs[port]['pkts'] = pkt * self.nr_packets
            cfgs[port]['port'] = port
            cfgs[port]['vpp'] = copy.deepcopy(set_port(punt_l4, port))

            # configure punt sockets
            cfgs[port]['sock'] = self.socket_client_create(
                "%s/socket_%d" % (self.tempdir, port))
            self.vapi.punt_socket_register(
                cfgs[port]['vpp'],
                "%s/socket_%d" % (self.tempdir, port))

        #
        # send the packets that get punted
        #
        for cfg in cfgs.values():
            self.send_and_assert_no_replies(self.pg0, cfg['pkts'])

        #
        # test that we got the excepted packets on the expected socket
        #
        for cfg in cfgs.values():
            rx = cfg['sock'].close()
            self.verify_udp_pkts(rx, len(cfg['pkts']), cfg['port'])
            self.vapi.punt_socket_deregister(cfg['vpp'])

    def test_punt_socket_traffic_multi_ports_single_socket(self):
        """ Punt socket traffic multi ports and single socket"""

        pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
        punt_l4 = mk_vpp_cfg4()

        #
        # create stream of packets with each port
        #
        pkts = []
        for port in self.ports:
            # choose port from port list
            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=9876, dport=port) /
                   Raw(b'\xa5' * 100))
            pkts += pkt * self.nr_packets

        #
        # configure a punt socket
        #
        self.socket_client_create("%s/socket_multi" % self.tempdir)
        for p in self.ports:
            self.vapi.punt_socket_register(set_port(punt_l4, p),
                                           "%s/socket_multi" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), len(self.ports))

        #
        # expect punt socket and no packets on pg0
        #
        self.send_and_assert_no_replies(self.pg0, pkts)
        self.logger.info(self.vapi.cli("show trace"))
        rx = self.socket_client_close()

        for p in self.ports:
            self.verify_udp_pkts(rx, self.nr_packets, p)
            self.vapi.punt_socket_deregister(set_port(punt_l4, p))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)


class TestIP6PuntSocket(TestPuntSocket):
    """ Punt Socket for IPv6 UDP """

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

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

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

        for i in self.pg_interfaces:
            i.config_ip6()
            i.resolve_ndp()

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

    def test_punt_socket_dump(self):
        """ Punt socket registration """

        pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
        af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
        udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
        #
        # configure a punt socket
        #
        punt_l4 = {
            'type': pt_l4,
            'punt': {
                'l4': {
                    'af': af_ip6,
                    'protocol': udp_proto
                }
            }
        }

        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

        #
        # configure a punt socket
        #
        self.vapi.punt_socket_register(set_port(punt_l4, 1111),
                                       "%s/socket_1111" % self.tempdir)
        self.vapi.punt_socket_register(set_port(punt_l4, 2222),
                                       "%s/socket_2222" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 2)
        self.verify_port(set_port(punt_l4, 1111), punts[0])
        self.verify_port(set_port(punt_l4, 2222), punts[1])

        #
        # deregister a punt socket
        #
        self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 1)

        #
        # configure a punt socket again
        #
        self.vapi.punt_socket_register(set_port(punt_l4, 1111),
                                       "%s/socket_1111" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 2)

        #
        # deregister all punt socket
        #
        self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
        self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
        self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

    def test_punt_socket_traffic_single_port_single_socket(self):
        """ Punt socket traffic single port single socket"""

        port = self.ports[0]
        pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
        af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
        udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
        punt_l4 = {
            'type': pt_l4,
            'punt': {
                'l4': {
                    'af': af_ip6,
                    'protocol': udp_proto,
                    'port': port,
                }
            }
        }

        p = (Ether(src=self.pg0.remote_mac,
                   dst=self.pg0.local_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
             inet6.UDP(sport=9876, dport=port) /
             Raw(b'\xa5' * 100))

        pkts = p * self.nr_packets

        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

        #
        # expect ICMPv6 - destination unreachable for all packets
        #
        self.vapi.cli("clear trace")
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        # FIXME - when punt socket deregister is implemented
        # rx = self.pg0.get_capture(self.nr_packets)
        # for p in rx:
        #     self.assertEqual(int(p[IPv6].nh), 58)                # ICMPv6
        #     self.assertEqual(int(p[ICMPv6DestUnreach].code),4)  # unreachable

        #
        # configure a punt socket
        #
        self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
        self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" %
                                       (self.tempdir, port))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 1)

        #
        # expect punt socket and no packets on pg0
        #
        self.vapi.cli("clear errors")
        self.vapi.cli("clear trace")
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        self.pg0.get_capture(0)
        self.logger.info(self.vapi.cli("show trace"))
        rx = self.socket_client_close()
        self.verify_udp_pkts(rx, len(pkts), port)

        #
        # remove punt socket. expect ICMP - dest. unreachable for all packets
        #
        self.vapi.punt_socket_deregister(punt_l4)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        # FIXME - when punt socket deregister is implemented
        # self.pg0.get_capture(nr_packets)

    def test_punt_socket_traffic_multi_ports_multi_sockets(self):
        """ Punt socket traffic multi ports and multi sockets"""

        punt_l4 = mk_vpp_cfg6()

        # configuration for each UDP port
        cfgs = dict()

        #
        # create stream of packets for each port
        #
        for port in self.ports:
            # choose port from port list
            cfgs[port] = {}

            pkt = (Ether(src=self.pg0.remote_mac,
                         dst=self.pg0.local_mac) /
                   IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
                   UDP(sport=9876, dport=port) /
                   Raw(b'\xa5' * 100))
            cfgs[port]['pkts'] = pkt * self.nr_packets
            cfgs[port]['port'] = port
            cfgs[port]['vpp'] = copy.deepcopy(set_port(punt_l4, port))

            # configure punt sockets
            cfgs[port]['sock'] = self.socket_client_create(
                "%s/socket_%d" % (self.tempdir, port))
            self.vapi.punt_socket_register(
                cfgs[port]['vpp'],
                "%s/socket_%d" % (self.tempdir, port))

        #
        # send the packets that get punted
        #
        for cfg in cfgs.values():
            self.send_and_assert_no_replies(self.pg0, cfg['pkts'])

        #
        # test that we got the excepted packets on the expected socket
        #
        for cfg in cfgs.values():
            rx = cfg['sock'].close()
            self.verify_udp_pkts(rx, len(cfg['pkts']), cfg['port'])
            self.vapi.punt_socket_deregister(cfg['vpp'])

    def test_punt_socket_traffic_multi_ports_single_socket(self):
        """ Punt socket traffic multi ports and single socket"""

        pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
        af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
        udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
        punt_l4 = {
            'type': pt_l4,
            'punt': {
                'l4': {
                    'af': af_ip6,
                    'protocol': udp_proto,
                }
            }
        }

        #
        # create stream of packets with each port
        #
        pkts = []
        for port in self.ports:
            # choose port from port list
            pkt = (Ether(src=self.pg0.remote_mac,
                         dst=self.pg0.local_mac) /
                   IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
                   UDP(sport=9876, dport=port) /
                   Raw(b'\xa5' * 100))
            pkts += pkt * self.nr_packets

        #
        # no punt socket
        #
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)

        #
        # configure a punt socket
        #
        self.socket_client_create("%s/socket_multi" % self.tempdir)
        for p in self.ports:
            self.vapi.punt_socket_register(set_port(punt_l4, p),
                                           "%s/socket_multi" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), len(self.ports))

        #
        # expect punt socket and no packets on pg0
        #
        self.vapi.cli("clear errors")
        self.vapi.cli("clear trace")
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        # give a chance to punt socket to collect all packets
        self.sleep(1)
        self.pg0.get_capture(0)
        rx = self.socket_client_close()

        for p in self.ports:
            self.verify_udp_pkts(rx, self.nr_packets, p)
            self.vapi.punt_socket_deregister(set_port(punt_l4, p))
        punts = self.vapi.punt_socket_dump(type=pt_l4)
        self.assertEqual(len(punts), 0)


class TestExceptionPuntSocket(TestPuntSocket):
    """ Punt Socket for Exceptions """

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

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

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

        self.create_pg_interfaces(range(2))
        for i in self.pg_interfaces:
            i.config_ip4()
            i.resolve_arp()

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

    def test_registration(self):
        """ Punt socket registration/deregistration"""

        pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION

        punts = self.vapi.punt_socket_dump(type=pt_ex)
        self.assertEqual(len(punts), 0)

        #
        # configure a punt socket
        #
        punt_ex = {
            'type': pt_ex,
            'punt': {
                'exception': {}
            }
        }

        self.vapi.punt_socket_register(set_reason(punt_ex, 1),
                                       "%s/socket_punt_1" % self.tempdir)
        self.vapi.punt_socket_register(set_reason(punt_ex, 2),
                                       "%s/socket_punt_2" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_ex)
        self.assertEqual(len(punts), 2)
        self.verify_exception(set_reason(punt_ex, 1), punts[0])
        self.verify_exception(set_reason(punt_ex, 2), punts[1])

        #
        # deregister a punt socket
        #
        self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
        punts = self.vapi.punt_socket_dump(type=pt_ex)
        self.assertEqual(len(punts), 1)

        #
        # configure a punt socket again
        #
        self.vapi.punt_socket_register(set_reason(punt_ex, 1),
                                       "%s/socket_punt_1" % self.tempdir)
        self.vapi.punt_socket_register(set_reason(punt_ex, 3),
                                       "%s/socket_punt_3" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_ex)
        self.assertEqual(len(punts), 3)

        self.logger.info(self.vapi.cli("sh punt sock reg exception"))

        #
        # deregister all punt socket
        #
        self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
        self.vapi.punt_socket_deregister(set_reason(punt_ex, 2))
        self.vapi.punt_socket_deregister(set_reason(punt_ex, 3))
        punts = self.vapi.punt_socket_dump(type=pt_ex)
        self.assertEqual(len(punts), 0)

    def verify_esp_pkts(self, rxs, n_sent, spi, has_udp):
        self.assertEqual(len(rxs), n_sent)
        for rx in rxs:
            self.assertTrue(rx.haslayer(IP))
            self.assertTrue(rx.haslayer(ESP))
            self.assertEqual(rx[ESP].spi, spi)
            if has_udp:
                self.assertTrue(rx.haslayer(UDP))

    def test_traffic(self):
        """ Punt socket traffic """

        port = self.ports[0]
        pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
        punt_ex = {
            'type': pt_ex,
            'punt': {
                'exception': {}
            }
        }

        #
        # we're dealing with IPSec tunnels punting for no-such-tunnel
        # (SPI=0 goes to ikev2)
        #
        cfgs = dict()
        cfgs['ipsec4-no-such-tunnel'] = {'spi': 99,
                                         'udp': False,
                                         'itf': self.pg0}

        #
        # find the VPP ID for these punt exception reasin
        #
        rs = self.vapi.punt_reason_dump()
        for key in cfgs:
            for r in rs:
                print(r.reason.name)
                print(key)
                if r.reason.name == key:
                    cfgs[key]['id'] = r.reason.id
                    cfgs[key]['vpp'] = copy.deepcopy(
                        set_reason(punt_ex,
                                   cfgs[key]['id']))
                    break

        #
        # configure punt sockets
        #
        for cfg in cfgs.values():
            cfg['sock'] = self.socket_client_create("%s/socket_%d" %
                                                    (self.tempdir, cfg['id']))
            self.vapi.punt_socket_register(
                cfg['vpp'], "%s/socket_%d" % (self.tempdir, cfg['id']))

        #
        # create packet streams for 'no-such-tunnel' exception
        #
        for cfg in cfgs.values():
            pkt = (Ether(src=cfg['itf'].remote_mac,
                         dst=cfg['itf'].local_mac) /
                   IP(src=cfg['itf'].remote_ip4,
                      dst=cfg['itf'].local_ip4))
            if (cfg['udp']):
                pkt = pkt / UDP(sport=666, dport=4500)
            pkt = (pkt / ESP(spi=cfg['spi'], seq=3) /
                   Raw(b'\xa5' * 100))
            cfg['pkts'] = [pkt]

        #
        # send packets for each SPI we expect to be punted
        #
        for cfg in cfgs.values():
            self.send_and_assert_no_replies(cfg['itf'], cfg['pkts'])

        #
        # verify the punted packets arrived on the associated socket
        #
        for cfg in cfgs.values():
            rx = cfg['sock'].close()
            self.verify_esp_pkts(rx, len(cfg['pkts']),
                                 cfg['spi'], cfg['udp'])

        #
        # add some tunnels, make sure it still punts
        #
        tun = VppIpsecInterface(self).add_vpp_config()
        sa_in = VppIpsecSA(self, 11, 11,
                           (VppEnum.vl_api_ipsec_integ_alg_t.
                            IPSEC_API_INTEG_ALG_SHA1_96),
                           b"0123456701234567",
                           (VppEnum.vl_api_ipsec_crypto_alg_t.
                            IPSEC_API_CRYPTO_ALG_AES_CBC_128),
                           b"0123456701234567",
                           50,
                           self.pg0.local_ip4,
                           self.pg0.remote_ip4).add_vpp_config()
        sa_out = VppIpsecSA(self, 22, 22,
                            (VppEnum.vl_api_ipsec_integ_alg_t.
                             IPSEC_API_INTEG_ALG_SHA1_96),
                            b"0123456701234567",
                            (VppEnum.vl_api_ipsec_crypto_alg_t.
                             IPSEC_API_CRYPTO_ALG_AES_CBC_128),
                            b"0123456701234567",
                            50,
                            self.pg0.local_ip4,
                            self.pg0.remote_ip4).add_vpp_config()
        protect = VppIpsecTunProtect(self, tun,
                                     sa_out,
                                     [sa_in]).add_vpp_config()

        #
        # send packets for each SPI we expect to be punted
        #
        for cfg in cfgs.values():
            self.send_and_assert_no_replies(cfg['itf'], cfg['pkts'])

        #
        # verify the punted packets arrived on the associated socket
        #
        for cfg in cfgs.values():
            rx = cfg['sock'].close()
            self.verify_esp_pkts(rx, len(cfg['pkts']),
                                 cfg['spi'], cfg['udp'])
        #
        # socket deregister
        #
        for cfg in cfgs.values():
            self.vapi.punt_socket_deregister(cfg['vpp'])


class TestIpProtoPuntSocket(TestPuntSocket):
    """ Punt Socket for IP packets """

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

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

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

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

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

    def test_registration(self):
        """ Punt socket registration/deregistration"""

        af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
        pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
        proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
        proto_eigrp = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_EIGRP

        punts = self.vapi.punt_socket_dump(type=pt_ip)
        self.assertEqual(len(punts), 0)

        #
        # configure a punt socket
        #
        punt_ospf = {
            'type': pt_ip,
            'punt': {
                'ip_proto': {
                    'af': af_ip4,
                    'protocol': proto_ospf
                }
            }
        }
        punt_eigrp = {
            'type': pt_ip,
            'punt': {
                'ip_proto': {
                    'af': af_ip4,
                    'protocol': proto_eigrp
                }
            }
        }

        self.vapi.punt_socket_register(punt_ospf,
                                       "%s/socket_punt_1" % self.tempdir)
        self.vapi.punt_socket_register(punt_eigrp,
                                       "%s/socket_punt_2" % self.tempdir)
        self.logger.info(self.vapi.cli("sh punt sock reg ip"))
        punts = self.vapi.punt_socket_dump(type=pt_ip)
        self.assertEqual(len(punts), 2)
        self.verify_ip_proto(punt_ospf, punts[0])
        self.verify_ip_proto(punt_eigrp, punts[1])

        #
        # deregister a punt socket
        #
        self.vapi.punt_socket_deregister(punt_ospf)
        punts = self.vapi.punt_socket_dump(type=pt_ip)
        self.assertEqual(len(punts), 1)

        #
        # configure a punt socket again
        #
        self.vapi.punt_socket_register(punt_ospf,
                                       "%s/socket_punt_3" % self.tempdir)
        punts = self.vapi.punt_socket_dump(type=pt_ip)
        self.assertEqual(len(punts), 2)

        self.logger.info(self.vapi.cli("sh punt sock reg exception"))

        #
        # deregister all punt socket
        #
        self.vapi.punt_socket_deregister(punt_eigrp)
        self.vapi.punt_socket_deregister(punt_ospf)
        punts = self.vapi.punt_socket_dump(type=pt_ip)
        self.assertEqual(len(punts), 0)

    def verify_ospf_pkts(self, rxs, n_sent):
        self.assertEqual(len(rxs), n_sent)
        for rx in rxs:
            self.assertTrue(rx.haslayer(OSPF_Hdr))

    def test_traffic(self):
        """ Punt socket traffic """

        af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
        pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
        proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF

        #
        # configure a punt socket to capture OSPF packets
        #
        punt_ospf = {
            'type': pt_ip,
            'punt': {
                'ip_proto': {
                    'af': af_ip4,
                    'protocol': proto_ospf
                }
            }
        }

        #
        # create packet streams and configure a punt sockets
        #
        pkt = (Ether(src=self.pg0.remote_mac,
                     dst=self.pg0.local_mac) /
               IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
               OSPF_Hdr() /
               OSPFv3_Hello())
        pkts = pkt * 7

        sock = self.socket_client_create("%s/socket_1" % self.tempdir)
        self.vapi.punt_socket_register(
            punt_ospf, "%s/socket_1" % self.tempdir)

        #
        # send packets for each SPI we expect to be punted
        #
        self.send_and_assert_no_replies(self.pg0, pkts)

        #
        # verify the punted packets arrived on the associated socket
        #
        rx = sock.close()
        self.verify_ospf_pkts(rx, len(pkts))
        self.vapi.punt_socket_deregister(punt_ospf)


@tag_fixme_vpp_workers
class TestPunt(VppTestCase):
    """ Exception Punt Test Case """

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

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

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

        self.create_pg_interfaces(range(4))

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

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

    def test_punt(self):
        """ Exception Path testing """

        #
        # dump the punt registered reasons
        #  search for a few we know should be there
        #
        rs = self.vapi.punt_reason_dump()

        reasons = ["ipsec6-no-such-tunnel",
                   "ipsec4-no-such-tunnel",
                   "ipsec4-spi-o-udp-0"]

        for reason in reasons:
            found = False
            for r in rs:
                if r.reason.name == reason:
                    found = True
                    break
            self.assertTrue(found)

        #
        # Using the test CLI we will hook in a exception path to
        # send ACL deny packets out of pg0 and pg1.
        # the ACL is src,dst = 1.1.1.1,1.1.1.2
        #
        ip_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32,
                                [VppRoutePath(self.pg3.remote_ip4,
                                              self.pg3.sw_if_index)])
        ip_1_1_1_2.add_vpp_config()
        ip_1_2 = VppIpRoute(self, "1::2", 128,
                            [VppRoutePath(self.pg3.remote_ip6,
                                          self.pg3.sw_if_index,
                                          proto=DpoProto.DPO_PROTO_IP6)])
        ip_1_2.add_vpp_config()

        p4 = (Ether(src=self.pg2.remote_mac,
                    dst=self.pg2.local_mac) /
              IP(src="1.1.1.1", dst="1.1.1.2") /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))
        p6 = (Ether(src=self.pg2.remote_mac,
                    dst=self.pg2.local_mac) /
              IPv6(src="1::1", dst="1::2") /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))
        self.send_and_expect(self.pg2, p4*1, self.pg3)
        self.send_and_expect(self.pg2, p6*1, self.pg3)

        #
        # apply the punting features
        #
        self.vapi.cli("test punt pg2")

        #
        # dump the punt reasons to learn the IDs assigned
        #
        rs = self.vapi.punt_reason_dump(reason={'name': "reason-v4"})
        r4 = rs[0].reason.id
        rs = self.vapi.punt_reason_dump(reason={'name': "reason-v6"})
        r6 = rs[0].reason.id

        #
        # pkts now dropped
        #
        self.send_and_assert_no_replies(self.pg2, p4*NUM_PKTS)
        self.send_and_assert_no_replies(self.pg2, p6*NUM_PKTS)

        #
        # Check state:
        #  1 - node error counters
        #  2 - per-reason counters
        #    2, 3 are the index of the assigned punt reason
        #
        stats = self.statistics.get_err_counter(
            "/err/punt-dispatch/No registrations")
        self.assertEqual(stats, 2*NUM_PKTS)

        stats = self.statistics.get_counter("/net/punt")
        self.assertEqual(stats[0][r4]['packets'], NUM_PKTS)
        self.assertEqual(stats[0][r6]['packets'], NUM_PKTS)

        #
        # use the test CLI to test a client that punts exception
        # packets out of pg0
        #
        self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip4)
        self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip6)

        rx4s = self.send_and_expect(self.pg2, p4*NUM_PKTS, self.pg0)
        rx6s = self.send_and_expect(self.pg2, p6*NUM_PKTS, self.pg0)

        #
        # check the packets come out IP unmodified but destined to pg0 host
        #
        for rx in rx4s:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p4[IP].dst, rx[IP].dst)
            self.assertEqual(p4[IP].ttl, rx[IP].ttl)
        for rx in rx6s:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
            self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)

        stats = self.statistics.get_counter("/net/punt")
        self.assertEqual(stats[0][r4]['packets'], 2*NUM_PKTS)
        self.assertEqual(stats[0][r6]['packets'], 2*NUM_PKTS)

        #
        # add another registration for the same reason to send packets
        # out of pg1
        #
        self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip4)
        self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip6)

        self.vapi.cli("clear trace")
        self.pg2.add_stream(p4 * NUM_PKTS)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rxd = self.pg0.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p4[IP].dst, rx[IP].dst)
            self.assertEqual(p4[IP].ttl, rx[IP].ttl)
        rxd = self.pg1.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(p4[IP].dst, rx[IP].dst)
            self.assertEqual(p4[IP].ttl, rx[IP].ttl)

        self.vapi.cli("clear trace")
        self.pg2.add_stream(p6 * NUM_PKTS)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rxd = self.pg0.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
            self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
        rxd = self.pg1.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
            self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)

        stats = self.statistics.get_counter("/net/punt")
        self.assertEqual(stats[0][r4]['packets'], 3*NUM_PKTS)
        self.assertEqual(stats[0][r6]['packets'], 3*NUM_PKTS)

        self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
        self.logger.info(self.vapi.cli("show punt client"))
        self.logger.info(self.vapi.cli("show punt reason"))
        self.logger.info(self.vapi.cli("show punt stats"))
        self.logger.info(self.vapi.cli("show punt db"))


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