#!/usr/bin/env python3

import unittest

from framework import VppTestCase, VppTestRunner
from vpp_ip import DpoProto, INVALID_INDEX
from itertools import product

from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP, TCP, ICMP
from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
from scapy.layers.inet6 import IPv6, IPerror6, ICMPv6DestUnreach
from scapy.layers.inet6 import ICMPv6EchoRequest, ICMPv6EchoReply

import struct

from ipaddress import (
    ip_address,
    ip_network,
    IPv4Address,
    IPv6Address,
    IPv4Network,
    IPv6Network,
)

from vpp_object import VppObject
from vpp_papi import VppEnum

N_PKTS = 15
N_REMOTE_HOSTS = 3

SRC = 0
DST = 1


class CnatCommonTestCase(VppTestCase):
    """CNat common test class"""

    #
    # turn the scanner off whilst testing otherwise sessions
    # will time out
    #
    extra_vpp_punt_config = [
        "cnat",
        "{",
        "session-db-buckets",
        "64",
        "session-cleanup-timeout",
        "0.1",
        "session-max-age",
        "1",
        "tcp-max-age",
        "1",
        "scanner",
        "off",
        "}",
    ]

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

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


class Endpoint(object):
    """CNat endpoint"""

    def __init__(self, pg=None, pgi=None, port=0, is_v6=False, ip=None):
        self.port = port
        self.is_v6 = is_v6
        self.sw_if_index = INVALID_INDEX
        if pg is not None and pgi is not None:
            # pg interface specified and remote index
            self.ip = self.get_ip46(pg.remote_hosts[pgi])
        elif pg is not None:
            self.ip = None
            self.sw_if_index = pg.sw_if_index
        elif ip is not None:
            self.ip = ip
        else:
            self.ip = "::" if self.is_v6 else "0.0.0.0"

    def get_ip46(self, obj):
        if self.is_v6:
            return obj.ip6
        return obj.ip4

    def udpate(self, **kwargs):
        self.__init__(**kwargs)

    def _vpp_if_af(self):
        if self.is_v6:
            return VppEnum.vl_api_address_family_t.ADDRESS_IP6
        return VppEnum.vl_api_address_family_t.ADDRESS_IP4

    def encode(self):
        return {
            "addr": self.ip,
            "port": self.port,
            "sw_if_index": self.sw_if_index,
            "if_af": self._vpp_if_af(),
        }

    def __str__(self):
        return "%s:%d" % (self.ip, self.port)


class Translation(VppObject):
    def __init__(self, test, iproto, vip, paths):
        self._test = test
        self.vip = vip
        self.iproto = iproto
        self.paths = paths
        self.id = None

    def __str__(self):
        return "%s %s %s" % (self.vip, self.iproto, self.paths)

    def _vl4_proto(self):
        ip_proto = VppEnum.vl_api_ip_proto_t
        return {
            UDP: ip_proto.IP_API_PROTO_UDP,
            TCP: ip_proto.IP_API_PROTO_TCP,
        }[self.iproto]

    def _encoded_paths(self):
        return [
            {"src_ep": src.encode(), "dst_ep": dst.encode()}
            for (src, dst) in self.paths
        ]

    def add_vpp_config(self):
        r = self._test.vapi.cnat_translation_update(
            {
                "vip": self.vip.encode(),
                "ip_proto": self._vl4_proto(),
                "n_paths": len(self.paths),
                "paths": self._encoded_paths(),
            }
        )
        self._test.registry.register(self, self._test.logger)
        self.id = r.id
        return self

    def remove_vpp_config(self):
        assert self.id is not None
        self._test.vapi.cnat_translation_del(id=self.id)
        return self

    def query_vpp_config(self):
        for t in self._test.vapi.cnat_translation_dump():
            if self.id == t.translation.id:
                return t.translation
        return None


class CnatTestContext(object):
    """
    Usage :

    ctx = CnatTestContext(self, TCP, is_v6=True)

    # send pg0.remote[0]:1234 -> pg1.remote[0]:6661
    ctx.cnat_send(self.pg0, 0, 1234, self.pg1, 0, 6661)

    # We expect this to be NATed as
    # pg2.remote[0]:<anyport> -> pg1.remote[0]:6661
    ctx.cnat_expect(self.pg2, 0, None, self.pg1, 0, 6661)

    # After running cnat_expect, we can send back the received packet
    # and expect it be 'unnated' so that we get the original packet
    ctx.cnat_send_return().cnat_expect_return()

    # same thing for ICMP errors
    ctx.cnat_send_icmp_return_error().cnat_expect_icmp_error_return()
    """

    def __init__(self, test, L4PROTO, is_v6):
        self.L4PROTO = L4PROTO
        self.is_v6 = is_v6
        self._test = test

    def get_ip46(self, obj):
        if self.is_v6:
            return obj.ip6
        return obj.ip4

    @property
    def IP46(self):
        return IPv6 if self.is_v6 else IP

    def cnat_send(
        self, src_pg, src_id, src_port, dst_pg, dst_id, dst_port, no_replies=False
    ):
        if isinstance(src_id, int):
            self.src_addr = self.get_ip46(src_pg.remote_hosts[src_id])
        else:
            self.dst_addr = src_id
        if isinstance(dst_id, int):
            self.dst_addr = self.get_ip46(dst_pg.remote_hosts[dst_id])
        else:
            self.dst_addr = dst_id
        self.src_port = src_port  # also ICMP id
        self.dst_port = dst_port  # also ICMP type

        if self.L4PROTO in [TCP, UDP]:
            l4 = self.L4PROTO(sport=self.src_port, dport=self.dst_port)
        elif self.L4PROTO in [ICMP] and not self.is_v6:
            l4 = self.L4PROTO(id=self.src_port, type=self.dst_port)
        elif self.L4PROTO in [ICMP] and self.is_v6:
            l4 = ICMPv6EchoRequest(id=self.src_port)
        p1 = (
            Ether(src=src_pg.remote_mac, dst=src_pg.local_mac)
            / self.IP46(src=self.src_addr, dst=self.dst_addr)
            / l4
            / Raw()
        )

        if no_replies:
            self._test.send_and_assert_no_replies(src_pg, p1 * N_PKTS, dst_pg)
        else:
            self.rxs = self._test.send_and_expect(src_pg, p1 * N_PKTS, dst_pg)
        self.expected_src_pg = src_pg
        self.expected_dst_pg = dst_pg
        return self

    def cnat_expect(self, src_pg, src_id, src_port, dst_pg, dst_id, dst_port):
        if isinstance(src_id, int):
            self.expect_src_addr = self.get_ip46(src_pg.remote_hosts[src_id])
        else:
            self.expect_src_addr = src_id
        if isinstance(dst_id, int):
            self.expect_dst_addr = self.get_ip46(dst_pg.remote_hosts[dst_id])
        else:
            self.expect_dst_addr = dst_id
        self.expect_src_port = src_port
        self.expect_dst_port = dst_port

        if self.expect_src_port is None:
            if self.L4PROTO in [TCP, UDP]:
                self.expect_src_port = self.rxs[0][self.L4PROTO].sport
            elif self.L4PROTO in [ICMP] and not self.is_v6:
                self.expect_src_port = self.rxs[0][self.L4PROTO].id
            elif self.L4PROTO in [ICMP] and self.is_v6:
                self.expect_src_port = self.rxs[0][ICMPv6EchoRequest].id

        for rx in self.rxs:
            self._test.assert_packet_checksums_valid(rx)
            self._test.assertEqual(rx[self.IP46].dst, self.expect_dst_addr)
            self._test.assertEqual(rx[self.IP46].src, self.expect_src_addr)
            if self.L4PROTO in [TCP, UDP]:
                self._test.assertEqual(rx[self.L4PROTO].dport, self.expect_dst_port)
                self._test.assertEqual(rx[self.L4PROTO].sport, self.expect_src_port)
            elif self.L4PROTO in [ICMP] and not self.is_v6:
                self._test.assertEqual(rx[self.L4PROTO].type, self.expect_dst_port)
                self._test.assertEqual(rx[self.L4PROTO].id, self.expect_src_port)
            elif self.L4PROTO in [ICMP] and self.is_v6:
                self._test.assertEqual(rx[ICMPv6EchoRequest].id, self.expect_src_port)
        return self

    def cnat_send_return(self):
        """This sends the return traffic"""
        if self.L4PROTO in [TCP, UDP]:
            l4 = self.L4PROTO(sport=self.expect_dst_port, dport=self.expect_src_port)
        elif self.L4PROTO in [ICMP] and not self.is_v6:
            # icmp type 0 if echo reply
            l4 = self.L4PROTO(id=self.expect_src_port, type=0)
        elif self.L4PROTO in [ICMP] and self.is_v6:
            l4 = ICMPv6EchoReply(id=self.expect_src_port)
        src_mac = self.expected_dst_pg.remote_mac
        p1 = (
            Ether(src=src_mac, dst=self.expected_dst_pg.local_mac)
            / self.IP46(src=self.expect_dst_addr, dst=self.expect_src_addr)
            / l4
            / Raw()
        )

        self.return_rxs = self._test.send_and_expect(
            self.expected_dst_pg, p1 * N_PKTS, self.expected_src_pg
        )
        return self

    def cnat_expect_return(self):
        for rx in self.return_rxs:
            self._test.assert_packet_checksums_valid(rx)
            self._test.assertEqual(rx[self.IP46].dst, self.src_addr)
            self._test.assertEqual(rx[self.IP46].src, self.dst_addr)
            if self.L4PROTO in [TCP, UDP]:
                self._test.assertEqual(rx[self.L4PROTO].dport, self.src_port)
                self._test.assertEqual(rx[self.L4PROTO].sport, self.dst_port)
            elif self.L4PROTO in [ICMP] and not self.is_v6:
                # icmp type 0 if echo reply
                self._test.assertEqual(rx[self.L4PROTO].type, 0)
                self._test.assertEqual(rx[self.L4PROTO].id, self.src_port)
            elif self.L4PROTO in [ICMP] and self.is_v6:
                self._test.assertEqual(rx[ICMPv6EchoReply].id, self.src_port)
        return self

    def cnat_send_icmp_return_error(self):
        """
        This called after cnat_expect will send an icmp error
        on the reverse path
        """
        ICMPelem = ICMPv6DestUnreach(code=1) if self.is_v6 else ICMP(type=11)
        InnerIP = self.rxs[0][self.IP46]
        p1 = (
            Ether(
                src=self.expected_dst_pg.remote_mac, dst=self.expected_dst_pg.local_mac
            )
            / self.IP46(src=self.expect_dst_addr, dst=self.expect_src_addr)
            / ICMPelem
            / InnerIP
        )
        self.return_rxs = self._test.send_and_expect(
            self.expected_dst_pg, p1 * N_PKTS, self.expected_src_pg
        )
        return self

    def cnat_expect_icmp_error_return(self):
        ICMP46 = ICMPv6DestUnreach if self.is_v6 else ICMP
        IP46err = IPerror6 if self.is_v6 else IPerror
        L4err = TCPerror if self.L4PROTO is TCP else UDPerror
        for rx in self.return_rxs:
            self._test.assert_packet_checksums_valid(rx)
            self._test.assertEqual(rx[self.IP46].dst, self.src_addr)
            self._test.assertEqual(rx[self.IP46].src, self.dst_addr)
            self._test.assertEqual(rx[ICMP46][IP46err].src, self.src_addr)
            self._test.assertEqual(rx[ICMP46][IP46err].dst, self.dst_addr)
            self._test.assertEqual(rx[ICMP46][IP46err][L4err].sport, self.src_port)
            self._test.assertEqual(rx[ICMP46][IP46err][L4err].dport, self.dst_port)
        return self


# -------------------------------------------------------------------
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# -------------------------------------------------------------------


class TestCNatTranslation(CnatCommonTestCase):
    """CNat Translation"""

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

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

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

        self.create_pg_interfaces(range(3))
        self.pg0.generate_remote_hosts(N_REMOTE_HOSTS)
        self.pg1.generate_remote_hosts(N_REMOTE_HOSTS)

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

    def tearDown(self):
        for translation in self.translations:
            translation.remove_vpp_config()

        self.vapi.cnat_session_purge()
        self.assertFalse(self.vapi.cnat_session_dump())

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

    def cnat_translation(self):
        """CNat Translation"""
        self.logger.info(self.vapi.cli("sh cnat client"))
        self.logger.info(self.vapi.cli("sh cnat translation"))

        for nbr, translation in enumerate(self.translations):
            vip = translation.vip

            #
            # Test Flows to the VIP
            #
            ctx = CnatTestContext(self, translation.iproto, vip.is_v6)
            for src_pgi, sport in product(range(N_REMOTE_HOSTS), [1234, 1233]):
                # from client to vip
                ctx.cnat_send(self.pg0, src_pgi, sport, self.pg1, vip.ip, vip.port)
                dst_port = translation.paths[0][DST].port
                ctx.cnat_expect(self.pg0, src_pgi, sport, self.pg1, nbr, dst_port)
                # from vip to client
                ctx.cnat_send_return().cnat_expect_return()

                #
                # packets to the VIP that do not match a
                # translation are dropped
                #
                ctx.cnat_send(
                    self.pg0, src_pgi, sport, self.pg1, vip.ip, 6666, no_replies=True
                )

                #
                # packets from the VIP that do not match a
                # session are forwarded
                #
                ctx.cnat_send(self.pg1, nbr, 6666, self.pg0, src_pgi, sport)
                ctx.cnat_expect(self.pg1, nbr, 6666, self.pg0, src_pgi, sport)

            #
            # modify the translation to use a different backend
            #
            old_dst_port = translation.paths[0][DST].port
            translation.paths[0][DST].udpate(
                pg=self.pg2, pgi=0, port=5000, is_v6=vip.is_v6
            )
            translation.add_vpp_config()

            #
            # existing flows follow the old path
            #
            for src_pgi in range(N_REMOTE_HOSTS):
                for sport in [1234, 1233]:
                    # from client to vip
                    ctx.cnat_send(self.pg0, src_pgi, sport, self.pg1, vip.ip, vip.port)
                    ctx.cnat_expect(
                        self.pg0, src_pgi, sport, self.pg1, nbr, old_dst_port
                    )
                    # from vip to client
                    ctx.cnat_send_return().cnat_expect_return()

            #
            # new flows go to the new backend
            #
            for src_pgi in range(N_REMOTE_HOSTS):
                ctx.cnat_send(self.pg0, src_pgi, 9999, self.pg2, vip.ip, vip.port)
                ctx.cnat_expect(self.pg0, src_pgi, 9999, self.pg2, 0, 5000)

            self.logger.info(self.vapi.cli("sh cnat session verbose"))

        #
        # turn the scanner back on and wait until the sessions
        # all disapper
        #
        self.vapi.cli("test cnat scanner on")
        self.virtual_sleep(2)
        sessions = self.vapi.cnat_session_dump()
        self.assertEqual(len(sessions), 0)
        self.vapi.cli("test cnat scanner off")

        #
        # load some flows again and purge
        #
        for translation in self.translations:
            vip = translation.vip
            ctx = CnatTestContext(self, translation.iproto, vip.is_v6)
            for src_pgi in range(N_REMOTE_HOSTS):
                for sport in [1234, 1233]:
                    # from client to vip
                    ctx.cnat_send(self.pg0, src_pgi, sport, self.pg2, vip.ip, vip.port)
                    ctx.cnat_expect(self.pg0, src_pgi, sport, self.pg2, 0, 5000)

    def _test_icmp(self):

        #
        # Testing ICMP
        #
        for nbr, translation in enumerate(self.translations):
            vip = translation.vip
            ctx = CnatTestContext(self, translation.iproto, vip.is_v6)

            #
            # NATing ICMP errors
            #
            ctx.cnat_send(self.pg0, 0, 1234, self.pg1, vip.ip, vip.port)
            dst_port = translation.paths[0][DST].port
            ctx.cnat_expect(self.pg0, 0, 1234, self.pg1, nbr, dst_port)
            ctx.cnat_send_icmp_return_error().cnat_expect_icmp_error_return()

            #
            # ICMP errors with no VIP associated should not be
            # modified
            #
            ctx.cnat_send(self.pg0, 0, 1234, self.pg2, 0, vip.port)
            dst_port = translation.paths[0][DST].port
            ctx.cnat_expect(self.pg0, 0, 1234, self.pg2, 0, vip.port)
            ctx.cnat_send_icmp_return_error().cnat_expect_icmp_error_return()

    def _make_translations_v4(self):
        self.translations = []
        self.translations.append(
            Translation(
                self,
                TCP,
                Endpoint(ip="30.0.0.1", port=5555, is_v6=False),
                [
                    (
                        Endpoint(is_v6=False),
                        Endpoint(pg=self.pg1, pgi=0, port=4001, is_v6=False),
                    )
                ],
            ).add_vpp_config()
        )
        self.translations.append(
            Translation(
                self,
                TCP,
                Endpoint(ip="30.0.0.2", port=5554, is_v6=False),
                [
                    (
                        Endpoint(is_v6=False),
                        Endpoint(pg=self.pg1, pgi=1, port=4002, is_v6=False),
                    )
                ],
            ).add_vpp_config()
        )
        self.translations.append(
            Translation(
                self,
                UDP,
                Endpoint(ip="30.0.0.2", port=5553, is_v6=False),
                [
                    (
                        Endpoint(is_v6=False),
                        Endpoint(pg=self.pg1, pgi=2, port=4003, is_v6=False),
                    )
                ],
            ).add_vpp_config()
        )

    def _make_translations_v6(self):
        self.translations = []
        self.translations.append(
            Translation(
                self,
                TCP,
                Endpoint(ip="30::1", port=5555, is_v6=True),
                [
                    (
                        Endpoint(is_v6=True),
                        Endpoint(pg=self.pg1, pgi=0, port=4001, is_v6=True),
                    )
                ],
            ).add_vpp_config()
        )
        self.translations.append(
            Translation(
                self,
                TCP,
                Endpoint(ip="30::2", port=5554, is_v6=True),
                [
                    (
                        Endpoint(is_v6=True),
                        Endpoint(pg=self.pg1, pgi=1, port=4002, is_v6=True),
                    )
                ],
            ).add_vpp_config()
        )
        self.translations.append(
            Translation(
                self,
                UDP,
                Endpoint(ip="30::2", port=5553, is_v6=True),
                [
                    (
                        Endpoint(is_v6=True),
                        Endpoint(pg=self.pg1, pgi=2, port=4003, is_v6=True),
                    )
                ],
            ).add_vpp_config()
        )

    def test_icmp4(self):
        # """ CNat Translation icmp v4 """
        self._make_translations_v4()
        self._test_icmp()

    def test_icmp6(self):
        # """ CNat Translation icmp v6 """
        self._make_translations_v6()
        self._test_icmp()

    def test_cnat6(self):
        # """ CNat Translation ipv6 """
        self._make_translations_v6()
        self.cnat_translation()

    def test_cnat4(self):
        # """ CNat Translation ipv4 """
        self._make_translations_v4()
        self.cnat_translation()


class TestCNatSourceNAT(CnatCommonTestCase):
    """CNat Source NAT"""

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

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

    def _enable_disable_snat(self, is_enable=True):
        self.vapi.cnat_set_snat_addresses(
            snat_ip4=self.pg2.remote_hosts[0].ip4,
            snat_ip6=self.pg2.remote_hosts[0].ip6,
            sw_if_index=INVALID_INDEX,
        )
        self.vapi.feature_enable_disable(
            enable=1 if is_enable else 0,
            arc_name="ip6-unicast",
            feature_name="cnat-snat-ip6",
            sw_if_index=self.pg0.sw_if_index,
        )
        self.vapi.feature_enable_disable(
            enable=1 if is_enable else 0,
            arc_name="ip4-unicast",
            feature_name="cnat-snat-ip4",
            sw_if_index=self.pg0.sw_if_index,
        )

        policie_tbls = VppEnum.vl_api_cnat_snat_policy_table_t
        self.vapi.cnat_set_snat_policy(
            policy=VppEnum.vl_api_cnat_snat_policies_t.CNAT_POLICY_IF_PFX
        )
        for i in self.pg_interfaces:
            self.vapi.cnat_snat_policy_add_del_if(
                sw_if_index=i.sw_if_index,
                is_add=1 if is_enable else 0,
                table=policie_tbls.CNAT_POLICY_INCLUDE_V6,
            )
            self.vapi.cnat_snat_policy_add_del_if(
                sw_if_index=i.sw_if_index,
                is_add=1 if is_enable else 0,
                table=policie_tbls.CNAT_POLICY_INCLUDE_V4,
            )

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

        self.create_pg_interfaces(range(3))
        self.pg1.generate_remote_hosts(2)

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

        self._enable_disable_snat(is_enable=True)

    def tearDown(self):
        self._enable_disable_snat(is_enable=True)

        self.vapi.cnat_session_purge()
        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.unconfig_ip6()
            i.admin_down()
        super(TestCNatSourceNAT, self).tearDown()

    def test_snat_v6(self):
        # """ CNat Source Nat v6 """
        self.sourcenat_test_tcp_udp_conf(TCP, is_v6=True)
        self.sourcenat_test_tcp_udp_conf(UDP, is_v6=True)
        self.sourcenat_test_icmp_echo_conf(is_v6=True)

    def test_snat_v4(self):
        # """ CNat Source Nat v4 """
        self.sourcenat_test_tcp_udp_conf(TCP)
        self.sourcenat_test_tcp_udp_conf(UDP)
        self.sourcenat_test_icmp_echo_conf()

    def sourcenat_test_icmp_echo_conf(self, is_v6=False):
        ctx = CnatTestContext(self, ICMP, is_v6=is_v6)
        # 8 is ICMP type echo (v4 only)
        ctx.cnat_send(self.pg0, 0, 0xFEED, self.pg1, 0, 8)
        ctx.cnat_expect(self.pg2, 0, None, self.pg1, 0, 8)
        ctx.cnat_send_return().cnat_expect_return()

    def sourcenat_test_tcp_udp_conf(self, L4PROTO, is_v6=False):
        ctx = CnatTestContext(self, L4PROTO, is_v6)
        # we should source NAT
        ctx.cnat_send(self.pg0, 0, 1234, self.pg1, 0, 6661)
        ctx.cnat_expect(self.pg2, 0, None, self.pg1, 0, 6661)
        ctx.cnat_send_return().cnat_expect_return()

        # exclude dst address of pg1.1 from snat
        if is_v6:
            exclude_prefix = ip_network(
                "%s/100" % self.pg1.remote_hosts[1].ip6, strict=False
            )
        else:
            exclude_prefix = ip_network(
                "%s/16" % self.pg1.remote_hosts[1].ip4, strict=False
            )

        # add remote host to exclude list
        self.vapi.cnat_snat_policy_add_del_exclude_pfx(prefix=exclude_prefix, is_add=1)

        # We should not source NAT the id=1
        ctx.cnat_send(self.pg0, 0, 1234, self.pg1, 1, 6661)
        ctx.cnat_expect(self.pg0, 0, 1234, self.pg1, 1, 6661)
        ctx.cnat_send_return().cnat_expect_return()

        # But we should source NAT the id=0
        ctx.cnat_send(self.pg0, 0, 1234, self.pg1, 0, 6661)
        ctx.cnat_expect(self.pg2, 0, None, self.pg1, 0, 6661)
        ctx.cnat_send_return().cnat_expect_return()

        # remove remote host from exclude list
        self.vapi.cnat_snat_policy_add_del_exclude_pfx(prefix=exclude_prefix, is_add=0)
        self.vapi.cnat_session_purge()

        # We should source NAT again
        ctx.cnat_send(self.pg0, 0, 1234, self.pg1, 1, 6661)
        ctx.cnat_expect(self.pg2, 0, None, self.pg1, 1, 6661)
        ctx.cnat_send_return().cnat_expect_return()

        # test return ICMP error nating
        ctx.cnat_send(self.pg0, 0, 1234, self.pg1, 1, 6661)
        ctx.cnat_expect(self.pg2, 0, None, self.pg1, 1, 6661)
        ctx.cnat_send_icmp_return_error().cnat_expect_icmp_error_return()

        self.vapi.cnat_session_purge()


class TestCNatDHCP(CnatCommonTestCase):
    """CNat Translation"""

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

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

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

    def make_addr(self, sw_if_index, addr_id, is_v6):
        if is_v6:
            return "fd01:%x::%u" % (sw_if_index, addr_id + 1)
        return "172.16.%u.%u" % (sw_if_index, addr_id)

    def make_prefix(self, sw_if_index, addr_id, is_v6):
        if is_v6:
            return "%s/128" % self.make_addr(sw_if_index, addr_id, is_v6)
        return "%s/32" % self.make_addr(sw_if_index, addr_id, is_v6)

    def check_resolved(self, tr, addr_id, is_v6=False):
        qt = tr.query_vpp_config()
        self.assertEqual(
            str(qt.vip.addr), self.make_addr(tr.vip.sw_if_index, addr_id, is_v6)
        )
        self.assertEqual(len(qt.paths), len(tr.paths))
        for path_tr, path_qt in zip(tr.paths, qt.paths):
            src_qt = path_qt.src_ep
            dst_qt = path_qt.dst_ep
            src_tr, dst_tr = path_tr
            self.assertEqual(
                str(src_qt.addr), self.make_addr(src_tr.sw_if_index, addr_id, is_v6)
            )
            self.assertEqual(
                str(dst_qt.addr), self.make_addr(dst_tr.sw_if_index, addr_id, is_v6)
            )

    def add_del_address(self, pg, addr_id, is_add=True, is_v6=False):
        self.vapi.sw_interface_add_del_address(
            sw_if_index=pg.sw_if_index,
            prefix=self.make_prefix(pg.sw_if_index, addr_id, is_v6),
            is_add=1 if is_add else 0,
        )

    def _test_dhcp_v46(self, is_v6):
        self.create_pg_interfaces(range(4))
        for i in self.pg_interfaces:
            i.admin_up()
        paths = [
            (Endpoint(pg=self.pg1, is_v6=is_v6), Endpoint(pg=self.pg2, is_v6=is_v6)),
            (Endpoint(pg=self.pg1, is_v6=is_v6), Endpoint(pg=self.pg3, is_v6=is_v6)),
        ]
        ep = Endpoint(pg=self.pg0, is_v6=is_v6)
        t = Translation(self, TCP, ep, paths).add_vpp_config()
        # Add an address on every interface
        # and check it is reflected in the cnat config
        for pg in self.pg_interfaces:
            self.add_del_address(pg, addr_id=0, is_add=True, is_v6=is_v6)
        self.check_resolved(t, addr_id=0, is_v6=is_v6)
        # Add a new address on every interface, remove the old one
        # and check it is reflected in the cnat config
        for pg in self.pg_interfaces:
            self.add_del_address(pg, addr_id=1, is_add=True, is_v6=is_v6)
            self.add_del_address(pg, addr_id=0, is_add=False, is_v6=is_v6)
        self.check_resolved(t, addr_id=1, is_v6=is_v6)
        # remove the configuration
        for pg in self.pg_interfaces:
            self.add_del_address(pg, addr_id=1, is_add=False, is_v6=is_v6)
        t.remove_vpp_config()

    def test_dhcp_v4(self):
        self._test_dhcp_v46(False)

    def test_dhcp_v6(self):
        self._test_dhcp_v46(True)

    def test_dhcp_snat(self):
        self.create_pg_interfaces(range(1))
        for i in self.pg_interfaces:
            i.admin_up()
        self.vapi.cnat_set_snat_addresses(sw_if_index=self.pg0.sw_if_index)
        # Add an address on every interface
        # and check it is reflected in the cnat config
        for pg in self.pg_interfaces:
            self.add_del_address(pg, addr_id=0, is_add=True, is_v6=False)
            self.add_del_address(pg, addr_id=0, is_add=True, is_v6=True)
        r = self.vapi.cnat_get_snat_addresses()
        self.assertEqual(
            str(r.snat_ip4),
            self.make_addr(self.pg0.sw_if_index, addr_id=0, is_v6=False),
        )
        self.assertEqual(
            str(r.snat_ip6), self.make_addr(self.pg0.sw_if_index, addr_id=0, is_v6=True)
        )
        # Add a new address on every interface, remove the old one
        # and check it is reflected in the cnat config
        for pg in self.pg_interfaces:
            self.add_del_address(pg, addr_id=1, is_add=True, is_v6=False)
            self.add_del_address(pg, addr_id=1, is_add=True, is_v6=True)
            self.add_del_address(pg, addr_id=0, is_add=False, is_v6=False)
            self.add_del_address(pg, addr_id=0, is_add=False, is_v6=True)
        r = self.vapi.cnat_get_snat_addresses()
        self.assertEqual(
            str(r.snat_ip4),
            self.make_addr(self.pg0.sw_if_index, addr_id=1, is_v6=False),
        )
        self.assertEqual(
            str(r.snat_ip6), self.make_addr(self.pg0.sw_if_index, addr_id=1, is_v6=True)
        )
        # remove the configuration
        for pg in self.pg_interfaces:
            self.add_del_address(pg, addr_id=1, is_add=False, is_v6=False)
            self.add_del_address(pg, addr_id=1, is_add=False, is_v6=True)
        self.vapi.cnat_set_snat_addresses(sw_if_index=INVALID_INDEX)


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