Exemple #1
0
    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()
Exemple #2
0
    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()
Exemple #3
0
    def test_bond_enslave(self):
        """ Bond enslave/detach slave test """

        # create interface (BondEthernet0)
        self.logger.info("create bond")
        bond0 = VppBondInterface(self, mode=3)
        bond0.add_vpp_config()
        bond0.admin_up()

        # 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()
Exemple #4
0
    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,
                                 use_custom_mac=1,
                                 mac_address=mac)
        bond0.add_vpp_config()
        bond0.admin_up()
        bond0_addr = socket.inet_pton(socket.AF_INET, "10.10.10.1")
        self.vapi.sw_interface_add_del_address(bond0.sw_if_index,
                                               bond0_addr,
                                               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 arp"))

        # 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))

        # 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('\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('\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 arp static BondEthernet0 10.10.10.12 abcd.abcd.0002"))
        self.logger.info(self.vapi.cli(
            "set ip arp 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()
Exemple #5
0
    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,
                                 use_custom_mac=1,
                                 mac_address=mac)
        bond0.add_vpp_config()
        bond0.admin_up()
        bond0_addr = socket.inet_pton(socket.AF_INET, "10.10.10.1")
        self.vapi.sw_interface_add_del_address(sw_if_index=bond0.sw_if_index,
                                               address=bond0_addr,
                                               address_length=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 arp"))

        # 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))

        # 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('\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('\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 arp static BondEthernet0 10.10.10.12 abcd.abcd.0002"))
        self.logger.info(self.vapi.cli(
            "set ip arp 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()
Exemple #6
0
    def test_marker_request(self):
        """ Marker Request test """

        # topology
        #
        #             +-+      +-+
        # memif1 -----|B|      |B|---- memif11
        #             |o|      |o|
        #             |n|------|n|
        #             |d|      |d|
        # pg0    -----|0|      |1|
        #             +-+      +-+

        socket1 = VppSocketFilename(self,
                                    socket_id=1,
                                    socket_filename="%s/memif.sock1" %
                                    self.tempdir)
        socket1.add_vpp_config()

        socket11 = VppSocketFilename(self,
                                     socket_id=2,
                                     socket_filename="%s/memif.sock1" %
                                     self.tempdir)
        socket11.add_vpp_config()

        memif1 = VppMemif(
            self,
            role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
            mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
            socket_id=1)
        memif1.add_vpp_config()
        memif1.admin_up()

        memif11 = VppMemif(
            self,
            role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
            mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
            socket_id=2)
        memif11.add_vpp_config()
        memif11.admin_up()

        bond0 = VppBondInterface(
            self,
            mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP,
            use_custom_mac=1,
            mac_address=bond_mac)

        bond0.add_vpp_config()
        bond0.admin_up()

        bond1 = VppBondInterface(
            self, mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)
        bond1.add_vpp_config()
        bond1.admin_up()

        bond0.enslave_vpp_bond_interface(sw_if_index=memif1.sw_if_index)
        bond1.enslave_vpp_bond_interface(sw_if_index=memif11.sw_if_index)

        # wait for memif protocol exchange and hardware carrier to come up
        self.assertEqual(memif1.wait_for_link_up(10), True)
        self.assertEqual(memif11.wait_for_link_up(10), True)

        # verify memif1 in bond0
        intfs = self.vapi.sw_interface_slave_dump(
            sw_if_index=bond0.sw_if_index)
        for intf in intfs:
            self.assertEqual(intf.sw_if_index, memif1.sw_if_index)

        # verify memif11 in bond1
        intfs = self.vapi.sw_interface_slave_dump(
            sw_if_index=bond1.sw_if_index)
        for intf in intfs:
            self.assertEqual(intf.sw_if_index, memif11.sw_if_index)

        self.vapi.ppcli("trace add memif-input 100")

        # create marker request
        marker = (Ether(src=bond_mac, dst=lacp_dst_mac) / SlowProtocol() /
                  MarkerProtocol(marker_type=1,
                                 requester_port=1,
                                 requester_system=bond_mac,
                                 requester_transaction_id=1))

        bond1.enslave_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)
        self.pg0.add_stream(marker)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        show_trace = self.vapi.ppcli("show trace max 100")
        self.assertIn("Marker Information TLV:", show_trace)

        bond0.remove_vpp_config()
        bond1.remove_vpp_config()
Exemple #7
0
    def test_lacp_connect(self):
        """ LACP protocol connect test """

        # topology
        #
        #             +-+      +-+
        # memif1 -----|B|      |B|---- memif11
        #             |o|      |o|
        #             |n|------|n|
        #             |d|      |d|
        # memif2 -----|0|      |1|---- memif12
        #             +-+      +-+

        socket1 = VppSocketFilename(self,
                                    socket_id=1,
                                    socket_filename="%s/memif.sock1" %
                                    self.tempdir)
        socket1.add_vpp_config()

        socket11 = VppSocketFilename(self,
                                     socket_id=2,
                                     socket_filename="%s/memif.sock1" %
                                     self.tempdir)
        socket11.add_vpp_config()

        socket2 = VppSocketFilename(self,
                                    socket_id=3,
                                    socket_filename="%s/memif.sock2" %
                                    self.tempdir)
        socket2.add_vpp_config()

        socket22 = VppSocketFilename(self,
                                     socket_id=4,
                                     socket_filename="%s/memif.sock2" %
                                     self.tempdir)
        socket22.add_vpp_config()

        memif1 = VppMemif(
            self,
            role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
            mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
            socket_id=1)
        memif1.add_vpp_config()
        memif1.admin_up()

        memif11 = VppMemif(
            self,
            role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
            mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
            socket_id=2)
        memif11.add_vpp_config()
        memif11.admin_up()

        memif2 = VppMemif(
            self,
            role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
            mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
            socket_id=3)
        memif2.add_vpp_config()
        memif2.admin_up()

        memif12 = VppMemif(
            self,
            role=VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
            mode=VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
            socket_id=4)
        memif12.add_vpp_config()
        memif12.admin_up()

        self.logger.info(self.vapi.ppcli("debug lacp on"))
        bond0 = VppBondInterface(
            self,
            mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP,
            use_custom_mac=1,
            mac_address=bond_mac)

        bond0.add_vpp_config()
        bond0.admin_up()

        bond1 = VppBondInterface(
            self, mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)
        bond1.add_vpp_config()
        bond1.admin_up()

        # enslave memif1 and memif2 to bond0
        bond0.enslave_vpp_bond_interface(sw_if_index=memif1.sw_if_index)
        bond0.enslave_vpp_bond_interface(sw_if_index=memif2.sw_if_index)

        # enslave memif11 and memif12 to bond1
        bond1.enslave_vpp_bond_interface(sw_if_index=memif11.sw_if_index)
        bond1.enslave_vpp_bond_interface(sw_if_index=memif12.sw_if_index)

        # wait for memif protocol exchange and hardware carrier to come up
        self.assertEqual(memif1.wait_for_link_up(10), True)
        self.assertEqual(memif2.wait_for_link_up(10), True)
        self.assertEqual(memif11.wait_for_link_up(10), True)
        self.assertEqual(memif12.wait_for_link_up(10), True)

        # verify memif1 and memif2 in bond0
        intfs = self.vapi.sw_interface_slave_dump(
            sw_if_index=bond0.sw_if_index)
        for intf in intfs:
            self.assertIn(intf.sw_if_index,
                          (memif1.sw_if_index, memif2.sw_if_index))

        # verify memif11 and memif12 in bond1
        intfs = self.vapi.sw_interface_slave_dump(
            sw_if_index=bond1.sw_if_index)
        for intf in intfs:
            self.assertIn(intf.sw_if_index,
                          (memif11.sw_if_index, memif12.sw_if_index))
            self.assertEqual(intf.is_long_timeout, 0)
            self.assertEqual(intf.is_passive, 0)

        # Let LACP create the bundle
        self.wait_for_lacp_connect(30)

        intfs = self.vapi.sw_interface_lacp_dump()
        for intf in intfs:
            self.assertEqual(intf.actor_state,
                             LACP_COLLECTION_AND_DISTRIBUTION_STATE)
            self.assertEqual(intf.partner_state,
                             LACP_COLLECTION_AND_DISTRIBUTION_STATE)

        intfs = self.vapi.sw_interface_bond_dump()
        for intf in intfs:
            self.assertEqual(intf.slaves, 2)
            self.assertEqual(intf.active_slaves, 2)
            self.assertEqual(intf.mode,
                             VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)

        self.logger.info(self.vapi.ppcli("show lacp"))
        self.logger.info(self.vapi.ppcli("show lacp details"))

        # detach slave memif1
        bond0.detach_vpp_bond_interface(sw_if_index=memif1.sw_if_index)

        self.wait_for_slave_detach(bond0, timeout=10, count=1)
        intfs = self.vapi.sw_interface_bond_dump()
        for intf in intfs:
            if (bond0.sw_if_index == intf.sw_if_index):
                self.assertEqual(intf.slaves, 1)
                self.assertEqual(intf.active_slaves, 1)
                self.assertEqual(intf.mode,
                                 VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)

        # detach slave memif2
        bond0.detach_vpp_bond_interface(sw_if_index=memif2.sw_if_index)
        self.wait_for_slave_detach(bond0, timeout=10, count=0)

        intfs = self.vapi.sw_interface_bond_dump()
        for intf in intfs:
            if (bond0.sw_if_index == intf.sw_if_index):
                self.assertEqual(intf.slaves, 0)
                self.assertEqual(intf.active_slaves, 0)

        bond0.remove_vpp_config()
        bond1.remove_vpp_config()