#!/usr/bin/env python3

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

from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6
from scapy.contrib.gtp import GTP_U_Header

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


@tag_fixme_vpp_workers
@unittest.skipIf("gtpu" in config.excluded_plugins, "Exclude GTPU plugin tests")
class TestGtpuUDP(VppTestCase):
    """GTPU UDP ports Test Case"""

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

        self.dport = 2152

        self.ip4_err = 0
        self.ip6_err = 0

        self.create_pg_interfaces(range(1))
        for pg in self.pg_interfaces:
            pg.admin_up()
        self.pg0.config_ip4()
        self.pg0.config_ip6()

    def _check_udp_port_ip4(self, enabled=True):
        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=self.dport, dport=self.dport, chksum=0)
        )

        self.pg0.add_stream(pkt)
        self.pg_start()

        err = self.statistics.get_counter("/err/ip4-udp-lookup/no_listener")[0]

        if enabled:
            self.assertEqual(err, self.ip4_err)
        else:
            self.assertEqual(err, self.ip4_err + 1)

        self.ip4_err = err

    def _check_udp_port_ip6(self, enabled=True):
        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=self.dport, dport=self.dport, chksum=0)
        )

        self.pg0.add_stream(pkt)
        self.pg_start()

        err = self.statistics.get_counter("/err/ip6-udp-lookup/no_listener")[0]

        if enabled:
            self.assertEqual(err, self.ip6_err)
        else:
            self.assertEqual(err, self.ip6_err + 1)

        self.ip6_err = err

    def test_udp_port(self):
        """test UDP ports
        Check if there are no udp listeners before gtpu is enabled
        """
        # UDP ports should be disabled unless a tunnel is configured
        self._check_udp_port_ip4(False)
        self._check_udp_port_ip6(False)

        r = self.vapi.gtpu_add_del_tunnel(
            is_add=True,
            mcast_sw_if_index=0xFFFFFFFF,
            decap_next_index=0xFFFFFFFF,
            src_address=self.pg0.local_ip4,
            dst_address=self.pg0.remote_ip4,
        )

        # UDP port 2152 enabled for ip4
        self._check_udp_port_ip4()

        r = self.vapi.gtpu_add_del_tunnel(
            is_add=True,
            mcast_sw_if_index=0xFFFFFFFF,
            decap_next_index=0xFFFFFFFF,
            src_address=self.pg0.local_ip6,
            dst_address=self.pg0.remote_ip6,
        )

        # UDP port 2152 enabled for ip6
        self._check_udp_port_ip6()

        r = self.vapi.gtpu_add_del_tunnel(
            is_add=False,
            mcast_sw_if_index=0xFFFFFFFF,
            decap_next_index=0xFFFFFFFF,
            src_address=self.pg0.local_ip4,
            dst_address=self.pg0.remote_ip4,
        )

        r = self.vapi.gtpu_add_del_tunnel(
            is_add=False,
            mcast_sw_if_index=0xFFFFFFFF,
            decap_next_index=0xFFFFFFFF,
            src_address=self.pg0.local_ip6,
            dst_address=self.pg0.remote_ip6,
        )


@unittest.skipIf("gtpu" in config.excluded_plugins, "Exclude GTPU plugin tests")
class TestGtpu(BridgeDomain, VppTestCase):
    """GTPU 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 GTPU 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)
            / GTP_U_Header(teid=vni, gtp_type=self.gtp_type, length=150)
            / 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 GTPU 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)
            / GTP_U_Header(teid=vni, gtp_type=self.gtp_type, length=150)
            / pkt
        )

    def decapsulate(self, pkt):
        """
        Decapsulate the original payload frame by removing GTPU header
        """
        return pkt[GTP_U_Header].payload

    # Method for checking GTPU encapsulation.
    #
    def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
        # 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 GTPU 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 GTPU 2152, source UDP port could be
        #  arbitrary.
        self.assertEqual(pkt[UDP].dport, type(self).dport)
        # Verify teid
        self.assertEqual(pkt[GTP_U_Header].teid, vni)

    def test_encap(self):
        """Encapsulation test
        Send frames from pg1
        Verify receipt of encapsulated frames on pg0
        """
        self.pg1.add_stream([self.frame_reply])

        self.pg0.enable_capture()

        self.pg_start()

        # Pick first received frame and check if it's correctly encapsulated.
        out = self.pg0.get_capture(1)
        pkt = out[0]
        self.check_encapsulation(pkt, self.single_tunnel_vni)

        # payload = self.decapsulate(pkt)
        # self.assert_eq_pkts(payload, self.frame_reply)

    def test_ucast_flood(self):
        """Unicast flood test
        Send frames from pg3
        Verify receipt of encapsulated frames on pg0
        """
        self.pg3.add_stream([self.frame_reply])

        self.pg0.enable_capture()

        self.pg_start()

        # Get packet from each tunnel and assert it's correctly encapsulated.
        out = self.pg0.get_capture(self.n_ucast_tunnels)
        for pkt in out:
            self.check_encapsulation(pkt, self.ucast_flood_bd, True)
            # payload = self.decapsulate(pkt)
            # self.assert_eq_pkts(payload, self.frame_reply)

    def test_mcast_flood(self):
        """Multicast flood test
        Send frames from pg2
        Verify receipt of encapsulated frames on pg0
        """
        self.pg2.add_stream([self.frame_reply])

        self.pg0.enable_capture()

        self.pg_start()

        # Pick first received frame and check if it's correctly encapsulated.
        out = self.pg0.get_capture(1)
        pkt = out[0]
        self.check_encapsulation(
            pkt, self.mcast_flood_bd, local_only=False, mcast_pkt=True
        )

        # payload = self.decapsulate(pkt)
        # self.assert_eq_pkts(payload, self.frame_reply)

    @classmethod
    def create_gtpu_flood_test_bd(cls, teid, n_ucast_tunnels):
        # Create 10 ucast gtpu 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.gtpu_add_del_tunnel(
                is_add=True,
                mcast_sw_if_index=0xFFFFFFFF,
                decap_next_index=0xFFFFFFFF,
                src_address=cls.pg0.local_ip4,
                dst_address=dest_ip4,
                teid=teid,
            )
            cls.vapi.sw_interface_set_l2_bridge(
                rx_sw_if_index=r.sw_if_index, bd_id=teid
            )

    @classmethod
    def add_del_shared_mcast_dst_load(cls, is_add):
        """
        add or del tunnels sharing the same mcast dst
        to test gtpu ref_count mechanism
        """
        n_shared_dst_tunnels = 20
        teid_start = 1000
        teid_end = teid_start + n_shared_dst_tunnels
        for teid in range(teid_start, teid_end):
            r = cls.vapi.gtpu_add_del_tunnel(
                decap_next_index=0xFFFFFFFF,
                src_address=cls.pg0.local_ip4,
                dst_address=cls.mcast_ip4,
                mcast_sw_if_index=1,
                teid=teid,
                is_add=is_add,
            )
            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 gtpu stability
        """
        n_distinct_dst_tunnels = 20
        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):
            teid = int(dest_ip4.split(".")[3])
            cls.vapi.gtpu_add_del_tunnel(
                decap_next_index=0xFFFFFFFF,
                src_address=cls.pg0.local_ip4,
                dst_address=dest_ip4,
                mcast_sw_if_index=1,
                teid=teid,
                is_add=is_add,
            )

    @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 GTPU 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(TestGtpu, cls).setUpClass()

        try:
            cls.dport = 2152
            cls.gtp_type = 0xFF

            # 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 GTPU VTEP on VPP pg0, and put gtpu_tunnel0 and pg1
            #  into BD.
            cls.single_tunnel_bd = 11
            cls.single_tunnel_vni = 11
            r = cls.vapi.gtpu_add_del_tunnel(
                is_add=True,
                mcast_sw_if_index=0xFFFFFFFF,
                decap_next_index=0xFFFFFFFF,
                src_address=cls.pg0.local_ip4,
                dst_address=cls.pg0.remote_ip4,
                teid=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 teid 2 to test multicast flooding
            cls.n_ucast_tunnels = 10
            cls.mcast_flood_bd = 12
            cls.create_gtpu_flood_test_bd(cls.mcast_flood_bd, cls.n_ucast_tunnels)
            r = cls.vapi.gtpu_add_del_tunnel(
                is_add=True,
                src_address=cls.pg0.local_ip4,
                dst_address=cls.mcast_ip4,
                mcast_sw_if_index=1,
                decap_next_index=0xFFFFFFFF,
                teid=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 teid 3 to test unicast flooding
            cls.ucast_flood_bd = 13
            cls.create_gtpu_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(TestGtpu, cls).tearDownClass()
            raise

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

    # 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(TestGtpu, self).tearDown()

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.cli("show bridge-domain 11 detail"))
        self.logger.info(self.vapi.cli("show bridge-domain 12 detail"))
        self.logger.info(self.vapi.cli("show bridge-domain 13 detail"))
        self.logger.info(self.vapi.cli("show int"))
        self.logger.info(self.vapi.cli("show gtpu tunnel"))
        self.logger.info(self.vapi.cli("show trace"))


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