#!/usr/bin/env python3

import socket
import unittest

from framework import VppTestCase, VppTestRunner
from scapy.packet import Raw
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from vpp_bond_interface import VppBondInterface
from vpp_papi import MACAddress, VppEnum


class TestBondInterface(VppTestCase):
    """Bond Test Case

    """

    @classmethod
    def setUpClass(cls):
        super(TestBondInterface, cls).setUpClass()
        # Test variables
        cls.pkts_per_burst = 257    # Number of packets per burst
        # create 3 pg interfaces
        cls.create_pg_interfaces(range(4))

        # packet sizes
        cls.pg_if_packet_sizes = [64, 512, 1518]  # , 9018]

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

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

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

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

    def show_commands_at_teardown(self):
        self.logger.info(self.vapi.ppcli("show interface"))

    def test_bond_traffic(self):
        """ Bond traffic test """

        # topology
        #
        # RX->              TX->
        #
        # pg2 ------+        +------pg0 (slave)
        #           |        |
        #          BondEthernet0 (10.10.10.1)
        #           |        |
        # pg3 ------+        +------pg1 (slave)
        #

        # create interface (BondEthernet0)
        #        self.logger.info("create bond")
        bond0_mac = "02:fe:38:30:59:3c"
        mac = MACAddress(bond0_mac).packed
        bond0 = VppBondInterface(self,
                                 mode=3,
                                 lb=1,
                                 numa_only=0,
                                 use_custom_mac=1,
                                 mac_address=mac)
        bond0.add_vpp_config()
        bond0.admin_up()
        self.vapi.sw_interface_add_del_address(
            sw_if_index=bond0.sw_if_index,
            prefix="10.10.10.1/24")

        self.pg2.config_ip4()
        self.pg2.resolve_arp()
        self.pg3.config_ip4()
        self.pg3.resolve_arp()

        self.logger.info(self.vapi.cli("show interface"))
        self.logger.info(self.vapi.cli("show interface address"))
        self.logger.info(self.vapi.cli("show ip neighbors"))

        # enslave pg0 and pg1 to BondEthernet0
        self.logger.info("bond enslave interface pg0 to BondEthernet0")
        bond0.enslave_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)
        self.logger.info("bond enslave interface pg1 to BondEthernet0")
        bond0.enslave_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index)

        # verify both slaves in BondEthernet0
        if_dump = self.vapi.sw_interface_slave_dump(bond0.sw_if_index)
        self.assertTrue(self.pg0.is_interface_config_in_dump(if_dump))
        self.assertTrue(self.pg1.is_interface_config_in_dump(if_dump))

        # generate a packet from pg2 -> BondEthernet0 -> pg1
        # BondEthernet0 TX hashes this packet to pg1
        p2 = (Ether(src=bond0_mac, dst=self.pg2.local_mac) /
              IP(src=self.pg2.local_ip4, dst="10.10.10.12") /
              UDP(sport=1235, dport=1235) /
              Raw(b'\xa5' * 100))
        self.pg2.add_stream(p2)

        # generate a packet from pg3 -> BondEthernet0 -> pg0
        # BondEthernet0 TX hashes this packet to pg0
        # notice the ip address and ports are different than p2 packet
        p3 = (Ether(src=bond0_mac, dst=self.pg3.local_mac) /
              IP(src=self.pg3.local_ip4, dst="10.10.10.11") /
              UDP(sport=1234, dport=1234) /
              Raw(b'\xa5' * 100))
        self.pg3.add_stream(p3)

        self.pg_enable_capture(self.pg_interfaces)

        # set up the static arp entries pointing to the BondEthernet0 interface
        # so that it does not try to resolve the ip address
        self.logger.info(self.vapi.cli(
            "set ip neighbor static BondEthernet0 10.10.10.12 abcd.abcd.0002"))
        self.logger.info(self.vapi.cli(
            "set ip neighbor static BondEthernet0 10.10.10.11 abcd.abcd.0004"))

        # clear the interface counters
        self.logger.info(self.vapi.cli("clear interfaces"))

        self.pg_start()

        self.logger.info("check the interface counters")

        # verify counters

        # BondEthernet0 tx bytes = 284
        intfs = self.vapi.cli("show interface BondEthernet0").split("\n")
        found = 0
        for intf in intfs:
            if "tx bytes" in intf and "284" in intf:
                found = 1
        self.assertEqual(found, 1)

        # BondEthernet0 tx bytes = 284
        intfs = self.vapi.cli("show interface BondEthernet0").split("\n")
        found = 0
        for intf in intfs:
            if "tx bytes" in intf and "284" in intf:
                found = 1
        self.assertEqual(found, 1)

        # pg2 rx bytes = 142
        intfs = self.vapi.cli("show interface pg2").split("\n")
        found = 0
        for intf in intfs:
            if "rx bytes" in intf and "142" in intf:
                found = 1
        self.assertEqual(found, 1)

        # pg3 rx bytes = 142
        intfs = self.vapi.cli("show interface pg3").split("\n")
        found = 0
        for intf in intfs:
            if "rx bytes" in intf and "142" in intf:
                found = 1
        self.assertEqual(found, 1)

        bond0.remove_vpp_config()

    def test_bond_enslave(self):
        """ Bond enslave/detach slave test """

        # create interface (BondEthernet0) and set bond mode to LACP
        self.logger.info("create bond")
        bond0 = VppBondInterface(self, mode=5)
        bond0.add_vpp_config()
        bond0.admin_up()

        # verify that interfaces can be enslaved and detached two times
        for i in range(2):
            # verify pg0 and pg1 not in BondEthernet0
            if_dump = self.vapi.sw_interface_slave_dump(bond0.sw_if_index)
            self.assertFalse(self.pg0.is_interface_config_in_dump(if_dump))
            self.assertFalse(self.pg1.is_interface_config_in_dump(if_dump))

            # enslave pg0 and pg1 to BondEthernet0
            self.logger.info("bond enslave interface pg0 to BondEthernet0")
            bond0.enslave_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index,
                                             is_passive=0,
                                             is_long_timeout=0)

            self.logger.info("bond enslave interface pg1 to BondEthernet0")
            bond0.enslave_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index,
                                             is_passive=0,
                                             is_long_timeout=0)
            # verify both slaves in BondEthernet0
            if_dump = self.vapi.sw_interface_slave_dump(bond0.sw_if_index)
            self.assertTrue(self.pg0.is_interface_config_in_dump(if_dump))
            self.assertTrue(self.pg1.is_interface_config_in_dump(if_dump))

            # detach interface pg0
            self.logger.info("detach interface pg0")
            bond0.detach_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)

            # verify pg0 is not in BondEthernet0, but pg1 is
            if_dump = self.vapi.sw_interface_slave_dump(bond0.sw_if_index)
            self.assertFalse(self.pg0.is_interface_config_in_dump(if_dump))
            self.assertTrue(self.pg1.is_interface_config_in_dump(if_dump))

            # detach interface pg1
            self.logger.info("detach interface pg1")
            bond0.detach_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index)

            # verify pg0 and pg1 not in BondEthernet0
            if_dump = self.vapi.sw_interface_slave_dump(bond0.sw_if_index)
            self.assertFalse(self.pg0.is_interface_config_in_dump(if_dump))
            self.assertFalse(self.pg1.is_interface_config_in_dump(if_dump))

        bond0.remove_vpp_config()

    def test_bond(self):
        """ Bond add/delete interface test """
        self.logger.info("Bond add interfaces")

        # create interface 1 (BondEthernet0)
        bond0 = VppBondInterface(self, mode=5)
        bond0.add_vpp_config()
        bond0.admin_up()

        # create interface 2 (BondEthernet1)
        bond1 = VppBondInterface(self, mode=3)
        bond1.add_vpp_config()
        bond1.admin_up()

        # verify both interfaces in the show
        ifs = self.vapi.cli("show interface")
        self.assertIn('BondEthernet0', ifs)
        self.assertIn('BondEthernet1', ifs)

        # verify they are in the dump also
        if_dump = self.vapi.sw_interface_bond_dump()
        self.assertTrue(bond0.is_interface_config_in_dump(if_dump))
        self.assertTrue(bond1.is_interface_config_in_dump(if_dump))

        # delete BondEthernet1
        self.logger.info("Deleting BondEthernet1")
        bond1.remove_vpp_config()

        self.logger.info("Verifying BondEthernet1 is deleted")

        ifs = self.vapi.cli("show interface")
        # verify BondEthernet0 still in the show
        self.assertIn('BondEthernet0', ifs)

        # verify BondEthernet1 not in the show
        self.assertNotIn('BondEthernet1', ifs)

        # verify BondEthernet1 is not in the dump
        if_dump = self.vapi.sw_interface_bond_dump()
        self.assertFalse(bond1.is_interface_config_in_dump(if_dump))

        # verify BondEthernet0 is still in the dump
        self.assertTrue(bond0.is_interface_config_in_dump(if_dump))

        # delete BondEthernet0
        self.logger.info("Deleting BondEthernet0")
        bond0.remove_vpp_config()

        self.logger.info("Verifying BondEthernet0 is deleted")

        # verify BondEthernet0 not in the show
        ifs = self.vapi.cli("show interface")
        self.assertNotIn('BondEthernet0', ifs)

        # verify BondEthernet0 is not in the dump
        if_dump = self.vapi.sw_interface_bond_dump()
        self.assertFalse(bond0.is_interface_config_in_dump(if_dump))

    def test_bond_link(self):
        """ Bond hw interface link state test """

        # for convenience
        bond_modes = VppEnum.vl_api_bond_mode_t
        intf_flags = VppEnum.vl_api_if_status_flags_t

        # create interface 1 (BondEthernet0)
        self.logger.info("Create bond interface")
        # use round-robin mode to avoid negotiation required by LACP
        bond0 = VppBondInterface(self,
                                 mode=bond_modes.BOND_API_MODE_ROUND_ROBIN)
        bond0.add_vpp_config()

        # initially admin state is down and link is down
        bond0.assert_interface_state(0, 0)

        # set bond admin up. confirm link down because no slaves are active
        self.logger.info("set interface BondEthernet0 admin up")
        bond0.admin_up()
        bond0.assert_interface_state(intf_flags.IF_STATUS_API_FLAG_ADMIN_UP, 0)

        # make sure slaves are down. enslave them to bond.
        self.logger.info("set interface pg0 admin down")
        self.pg0.admin_down()
        self.logger.info("bond enslave interface pg0 to BondEthernet0")
        bond0.enslave_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index,
                                         is_passive=0,
                                         is_long_timeout=0)
        self.logger.info("set interface pg1 admin down")
        self.pg1.admin_down()
        self.logger.info("bond enslave interface pg1 to BondEthernet0")
        bond0.enslave_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index,
                                         is_passive=0,
                                         is_long_timeout=0)

        # bring slaves up, confirm bond link is up
        self.logger.info("set interface pg0 admin up")
        self.pg0.admin_up()
        self.logger.info("set interface pg1 admin up")
        self.pg1.admin_up()
        bond0.assert_interface_state(intf_flags.IF_STATUS_API_FLAG_ADMIN_UP,
                                     intf_flags.IF_STATUS_API_FLAG_LINK_UP)

        # detach pg0, pg1
        self.logger.info("detach interface pg0")
        bond0.detach_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)
        self.logger.info("detach interface pg1")
        bond0.detach_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index)

        # link should be down now
        bond0.assert_interface_state(intf_flags.IF_STATUS_API_FLAG_ADMIN_UP, 0)

        # delete BondEthernet0
        self.logger.info("Deleting BondEthernet0")
        bond0.remove_vpp_config()


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