#!/usr/bin/env python3

from util import ip4_range
import unittest
from framework import VppTestCase
from asfframework import VppTestRunner
from template_bd import BridgeDomain
from config import config

from scapy.layers.l2 import Ether, ARP
from scapy.layers.inet import IP, UDP, ICMP
from scapy.contrib.geneve import GENEVE

import util
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_ip import INVALID_INDEX


@unittest.skipIf("geneve" in config.excluded_plugins, "Exclude GENEVE plugin tests")
class TestGeneve(BridgeDomain, VppTestCase):
    """GENEVE Test Case"""

    def __init__(self, *args):
        BridgeDomain.__init__(self)
        VppTestCase.__init__(self, *args)

    def encapsulate(self, pkt, vni):
        """
        Encapsulate the original payload frame by adding GENEVE header with its
        UDP, IP and Ethernet fields
        """
        return (
            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
            / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
            / UDP(sport=self.dport, dport=self.dport, chksum=0)
            / GENEVE(vni=vni)
            / pkt
        )

    def ip_range(self, start, end):
        """range of remote ip's"""
        return ip4_range(self.pg0.remote_ip4, start, end)

    def encap_mcast(self, pkt, src_ip, src_mac, vni):
        """
        Encapsulate the original payload frame by adding GENEVE header with its
        UDP, IP and Ethernet fields
        """
        return (
            Ether(src=src_mac, dst=self.mcast_mac)
            / IP(src=src_ip, dst=self.mcast_ip4)
            / UDP(sport=self.dport, dport=self.dport, chksum=0)
            / GENEVE(vni=vni)
            / pkt
        )

    def decapsulate(self, pkt):
        """
        Decapsulate the original payload frame by removing GENEVE header
        """
        # check if is set I flag
        # self.assertEqual(pkt[GENEVE].flags, int('0x8', 16))
        return pkt[GENEVE].payload

    # Method for checking GENEVE encapsulation.
    #
    def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
        # TODO: add error messages
        # Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
        #  by VPP using ARP.
        self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
        if not local_only:
            if not mcast_pkt:
                self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
            else:
                self.assertEqual(pkt[Ether].dst, type(self).mcast_mac)
        # Verify GENEVE tunnel source IP is VPP_IP and destination IP is MY_IP.
        self.assertEqual(pkt[IP].src, self.pg0.local_ip4)
        if not local_only:
            if not mcast_pkt:
                self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
            else:
                self.assertEqual(pkt[IP].dst, type(self).mcast_ip4)
        # Verify UDP destination port is GENEVE 4789, source UDP port could be
        #  arbitrary.
        self.assertEqual(pkt[UDP].dport, type(self).dport)
        # TODO: checksum check
        # Verify VNI
        self.assertEqual(pkt[GENEVE].vni, vni)

    @classmethod
    def create_geneve_flood_test_bd(cls, vni, n_ucast_tunnels):
        # Create 10 ucast geneve tunnels under bd
        ip_range_start = 10
        ip_range_end = ip_range_start + n_ucast_tunnels
        next_hop_address = cls.pg0.remote_ip4
        for dest_ip4 in ip4_range(next_hop_address, ip_range_start, ip_range_end):
            # add host route so dest_ip4 will not be resolved
            rip = VppIpRoute(
                cls,
                dest_ip4,
                32,
                [VppRoutePath(next_hop_address, INVALID_INDEX)],
                register=False,
            )
            rip.add_vpp_config()
            r = cls.vapi.geneve_add_del_tunnel(
                local_address=cls.pg0.local_ip4, remote_address=dest_ip4, vni=vni
            )
            cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index, bd_id=vni)

    @classmethod
    def add_del_shared_mcast_dst_load(cls, is_add):
        """
        add or del tunnels sharing the same mcast dst
        to test geneve ref_count mechanism
        """
        n_shared_dst_tunnels = 10
        vni_start = 10000
        vni_end = vni_start + n_shared_dst_tunnels
        for vni in range(vni_start, vni_end):
            r = cls.vapi.geneve_add_del_tunnel(
                local_address=cls.pg0.local_ip4,
                remote_address=cls.mcast_ip4,
                mcast_sw_if_index=1,
                is_add=is_add,
                vni=vni,
            )
            if r.sw_if_index == 0xFFFFFFFF:
                raise ValueError("bad sw_if_index: ~0")

    @classmethod
    def add_shared_mcast_dst_load(cls):
        cls.add_del_shared_mcast_dst_load(is_add=1)

    @classmethod
    def del_shared_mcast_dst_load(cls):
        cls.add_del_shared_mcast_dst_load(is_add=0)

    @classmethod
    def add_del_mcast_tunnels_load(cls, is_add):
        """
        add or del tunnels to test geneve stability
        """
        n_distinct_dst_tunnels = 10
        ip_range_start = 10
        ip_range_end = ip_range_start + n_distinct_dst_tunnels
        for dest_ip4 in ip4_range(cls.mcast_ip4, ip_range_start, ip_range_end):
            vni = int(dest_ip4.split(".")[3])
            cls.vapi.geneve_add_del_tunnel(
                local_address=cls.pg0.local_ip4,
                remote_address=dest_ip4,
                mcast_sw_if_index=1,
                is_add=is_add,
                vni=vni,
            )

    @classmethod
    def add_mcast_tunnels_load(cls):
        cls.add_del_mcast_tunnels_load(is_add=1)

    @classmethod
    def del_mcast_tunnels_load(cls):
        cls.add_del_mcast_tunnels_load(is_add=0)

    # Class method to start the GENEVE test case.
    #  Overrides setUpClass method in VppTestCase class.
    #  Python try..except statement is used to ensure that the tear down of
    #  the class will be executed even if exception is raised.
    #  @param cls The class pointer.
    @classmethod
    def setUpClass(cls):
        super(TestGeneve, cls).setUpClass()

        try:
            cls.dport = 6081

            # Create 2 pg interfaces.
            cls.create_pg_interfaces(range(4))
            for pg in cls.pg_interfaces:
                pg.admin_up()

            # Configure IPv4 addresses on VPP pg0.
            cls.pg0.config_ip4()

            # Resolve MAC address for VPP's IP address on pg0.
            cls.pg0.resolve_arp()

            # Our Multicast address
            cls.mcast_ip4 = "239.1.1.1"
            cls.mcast_mac = util.mcast_ip_to_mac(cls.mcast_ip4)

            # Create GENEVE VTEP on VPP pg0, and put geneve_tunnel0 and pg1
            #  into BD.
            cls.single_tunnel_vni = 0xABCDE
            cls.single_tunnel_bd = 1
            r = cls.vapi.geneve_add_del_tunnel(
                local_address=cls.pg0.local_ip4,
                remote_address=cls.pg0.remote_ip4,
                vni=cls.single_tunnel_vni,
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=r.sw_if_index, bd_id=cls.single_tunnel_bd
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=cls.pg1.sw_if_index, bd_id=cls.single_tunnel_bd
            )

            # Setup vni 2 to test multicast flooding
            cls.n_ucast_tunnels = 10
            cls.mcast_flood_bd = 2
            cls.create_geneve_flood_test_bd(cls.mcast_flood_bd, cls.n_ucast_tunnels)
            r = cls.vapi.geneve_add_del_tunnel(
                local_address=cls.pg0.local_ip4,
                remote_address=cls.mcast_ip4,
                mcast_sw_if_index=1,
                vni=cls.mcast_flood_bd,
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=r.sw_if_index, bd_id=cls.mcast_flood_bd
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=cls.pg2.sw_if_index, bd_id=cls.mcast_flood_bd
            )

            # Add and delete mcast tunnels to check stability
            cls.add_shared_mcast_dst_load()
            cls.add_mcast_tunnels_load()
            cls.del_shared_mcast_dst_load()
            cls.del_mcast_tunnels_load()

            # Setup vni 3 to test unicast flooding
            cls.ucast_flood_bd = 3
            cls.create_geneve_flood_test_bd(cls.ucast_flood_bd, cls.n_ucast_tunnels)
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=cls.pg3.sw_if_index, bd_id=cls.ucast_flood_bd
            )
        except Exception:
            super(TestGeneve, cls).tearDownClass()
            raise

    # Method to define VPP actions before tear down of the test case.
    #  Overrides tearDown method in VppTestCase class.
    #  @param self The object pointer.
    def tearDown(self):
        super(TestGeneve, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show bridge-domain 1 detail"))
        self.logger.info(self.vapi.cli("show bridge-domain 2 detail"))
        self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
        self.logger.info(self.vapi.cli("show geneve tunnel"))


@unittest.skipIf("geneve" in config.excluded_plugins, "Exclude GENEVE plugin tests")
class TestGeneveL3(VppTestCase):
    """GENEVE L3 Test Case"""

    @classmethod
    def setUpClass(cls):
        super(TestGeneveL3, cls).setUpClass()
        try:
            cls.create_pg_interfaces(range(2))
            cls.interfaces = list(cls.pg_interfaces)

            for i in cls.interfaces:
                i.admin_up()
                i.config_ip4()
                i.resolve_arp()
        except Exception:
            super(TestGeneveL3, cls).tearDownClass()
            raise

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

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

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show geneve tunnel"))
        self.logger.info(self.vapi.cli("show ip neighbor"))

    def test_l3_packet(self):
        vni = 1234
        r = self.vapi.add_node_next(
            node_name="geneve4-input", next_name="ethernet-input"
        )
        r = self.vapi.geneve_add_del_tunnel2(
            is_add=1,
            local_address=self.pg0.local_ip4,
            remote_address=self.pg0.remote_ip4,
            vni=vni,
            l3_mode=1,
            decap_next_index=r.next_index,
        )

        self.vapi.sw_interface_add_del_address(
            sw_if_index=r.sw_if_index, prefix="10.0.0.1/24"
        )

        pkt = (
            Ether(src=self.pg0.remote_mac, dst="d0:0b:ee:d0:00:00")
            / IP(src="10.0.0.2", dst="10.0.0.1")
            / ICMP()
        )

        encap = (
            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
            / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
            / UDP(sport=6081, dport=6081, chksum=0)
            / GENEVE(vni=vni)
        )

        arp = Ether(src=self.pg0.remote_mac, dst="d0:0b:ee:d0:00:00") / ARP(
            op="is-at",
            hwsrc=self.pg0.remote_mac,
            hwdst="d0:0b:ee:d0:00:00",
            psrc="10.0.0.2",
            pdst="10.0.0.1",
        )

        rx = self.send_and_expect(self.pg0, encap / pkt * 1, self.pg0)
        rx = self.send_and_assert_no_replies(self.pg0, encap / arp * 1, self.pg0)
        rx = self.send_and_expect(self.pg0, encap / pkt * 1, self.pg0)
        self.assertEqual(rx[0][ICMP].type, 0)  # echo reply

        r = self.vapi.geneve_add_del_tunnel2(
            is_add=0,
            local_address=self.pg0.local_ip4,
            remote_address=self.pg0.remote_ip4,
            vni=vni,
        )


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