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()
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_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()
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()
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()
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()
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()