def test06_verify_adding_same_prefix(self): # Add prefix on r2 with SLAAC flag self.r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True) self.wait_for_completion(self.device_list) # Verify the prefix and related address gets added verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.assertEqual([ node.find_ip6_address_with_prefix(PREFIX) for node in self.all_nodes ], self.slaac_addrs) # Add same prefix on r1 and verify addresses stay as before and related prefix entries gets # added on all the node. # r1 should have 3 prefix entries((1 as origin:ncp (with rloc16 of r1), 2nd as origin:user (with rloc:0x0000)) # and 3rd as origin:ncp (with rloc16 of r2). Similarly 3 prefix entries should be on r2. # On fed1 there should be 2 entries each from origin:ncp with rloc16 of r1 and r2 self.r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True) self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.assertEqual([ node.find_ip6_address_with_prefix(PREFIX) for node in self.all_nodes ], self.slaac_addrs)
def test03_Reset_NCP(self): # Reset the nodes and verify that all addresses/prefixes are preserved. self.fed1.reset_thread_radio() self.sed2.reset_thread_radio() self.wait_for_completion(self.device_list) wpan_util.verify_within(self.check_addresses_and_prefixes, wait_time=60, delay_time=10) # Remove address from `r2` self.r2.remove_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64) self.wait_for_completion(self.device_list) def check_address_prefix_removed(): # Verify that address is removed from r2 verify(self.r2.find_ip6_address_with_prefix(IP6_PREFIX_1) == "") # Verify that the related prefix is also removed on all nodes for node in self.all_nodes: prefixes = wpan_table_parser.parse_on_mesh_prefix_result( node.get(wpan.WPAN_THREAD_ON_MESH_PREFIXES)) for p in prefixes: verify(p.prefix != IP6_PREFIX_1) # Check the addresses and prefixes (wait time 15 seconds) wpan_util.verify_within(check_address_prefix_removed, wait_time=60, delay_time=10)
def test07_verify_sed_forced_switch_to_parent_r3(self): # Force sed to switch its parent from r1 to r3 # # r3 ---- r1 ---- r2 # | \ # | \ # ed3 sed self.r1.un_allowlist_node(self.sed) self.r3.allowlist_node(self.sed) self.sed.allowlist_node(self.r3) # Wait for sed to detach from r1 and attach to r3. def check_sed_is_removed_from_r1_child_table(): child_table = self.r1.wpanctl( "get", "get " + wpan.WPAN_THREAD_CHILD_TABLE, 2) child_table = wpan_table_parser.parse_child_table_address_result( child_table) verify(len(child_table) == 0) verify_within(check_sed_is_removed_from_r1_child_table, REATTACH_WAIT_TIME) # check that sed is now a child of r3 (r3 should have two child, sed and ed3) child_table = self.r3.wpanctl("get", "get " + wpan.WPAN_THREAD_CHILD_TABLE, 2) child_table = wpan_table_parser.parse_child_table_address_result( child_table) verify(len(child_table) == 2)
def test05_child_quick_re_attach_after_parent_reset(self): # Check the child recovery after a parent reset using quick re-attach # achieved via "Child Update" exchange. self.logger.info("Disable supervision check on the child {}.".format( self.child.name)) self.child.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, "1000") self.child.set(wpan.WPAN_POLL_INTERVAL, "10000") time.sleep(0.1) # We use the "stat:ncp" wpantund property to verify that child does not # get detached. child_num_state_changes = len( wpan_table_parser.parse_list(self.child.get("stat:ncp"))) # Reset parent and wait for it to be associated. self.parent.reset_thread_radio() self.wait_for_completion(self.device_list) def check_parent_is_associated(): verify(is_associated(self.parent)) verify_within(check_parent_is_associated, WAIT_TIME) self.child.set(wpan.WPAN_POLL_INTERVAL, "100") # Verify that we again see all the child addresses in the parent's child # table. Note that child should register its addresses using "Child Update # Request" exchange. verify_within(self.check_child_addresses_on_parent, WAIT_TIME) # Verify that there was no state change on child. self.assertEqual( child_num_state_changes, len(wpan_table_parser.parse_list(self.child.get("stat:ncp"))))
def test03_Change_Parent(self): # Remove the `child` from allowlist of `parent2` and add it to allowlist of `parent1` instead. self.child_num_state_changes = len( wpan_table_parser.parse_list(self.child1.get("stat:ncp"))) print(self.child_num_state_changes) self.parent1.allowlist_node(self.child1) self.parent2.un_allowlist_node(self.child1) # Enable supervision check on the `child` and also on `parent1`. self.child1.setprop(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, str(CHILD_SUPERVISION_CHECK_TIMEOUT)) self.parent1.setprop(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL)) # Since child supervision is not enabled on `parent2` and the `child` is # removed from allowlist on `parent2`, after the supervision check timeout # the `child` should realize that it can no longer talk to its current # parent (`parent2`) and try to reattach. All re-attach attempts to `parent2` # should fail (due to allowlist) and cause the `child` to get detached and # search for a new parent and then attach to `parent1`. # # To verify that the `child` does get detached and attach to a new parent, we # monitor the number of state changes using wpantund property "stat:ncp". verify_within(self.check_child_is_reattached, 60, 5)
def test10_verify_sed2_forced_switch_again_to_parent_r3(self): # Force sed2 to switch its parent from r2 to r3 self.sed2.setprop(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, str(CHILD_SUPERVISION_CHECK_TIMEOUT)) self.r3.setprop(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, str(PARENT_SUPERVISION_INTERVAL)) self.r2.un_allowlist_node(self.sed2) self.r3.allowlist_node(self.sed2) self.sed2.allowlist_node(self.r3) # Wait for sed2 to detach from r2 and attach to r3. # # Upon re-attach, previous parent r2 is notified and should remove sed2 from its child table. def check_sed2_is_removed_from_r2_child_table(): child_table = self.r2.wpanctl( "get", "get " + wpan.WPAN_THREAD_CHILD_TABLE, 2) child_table = wpan_table_parser.parse_child_table_address_result( child_table) verify(len(child_table) == 0) verify_within(check_sed2_is_removed_from_r2_child_table, REATTACH_WAIT_TIME) # Verify that both sed2, fed3 are children of r3 child_table = self.r3.wpanctl("get", "get " + wpan.WPAN_THREAD_CHILD_TABLE, 2) child_table = wpan_table_parser.parse_child_table_address_result( child_table) verify(len(child_table) == 2)
def test05_Verify_Parent_Reset(self): # Reset parent and verify all children are recovered self.parent.reset_thread_radio() self.wait_for_completion(self.device_list) verify_within(self.check_child_table, WAIT_INTERVAL)
def test11_remove_ipv6_address_for_same_prefix(self): # Check behavior when a user-added address with same prefix is removed from r1 # SLAAC module should add a SLAAC address as same slaac prefix is present on r2. self.r1.remove_ip6_address_on_interface(IP_ADDRESS) verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.assertEqual([ node.find_ip6_address_with_prefix(PREFIX) for node in self.all_nodes ], self.slaac_addrs) # Re-add the address self.r1.add_ip6_address_on_interface(IP_ADDRESS) # Remove the SLAAC PREFIX on r2. self.r2.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) def check_ip6_addresses(): # Verify that SLAAC addresses are removed on r2 and fed1 wpan_util.verify_no_address([self.r2, self.fed1], PREFIX) # And that user-added address matching the prefix is not removed on r1 r1_addrs = wpan_table_parser.parse_list( self.r1.get(wpan.WPAN_IP6_ALL_ADDRESSES)) verify(IP_ADDRESS in r1_addrs) verify_within(check_ip6_addresses, WAIT_INTERVAL) self.r1.remove_ip6_address_on_interface(IP_ADDRESS)
def test02_add_prefixes(self): # Add 4 prefixes (all with SLAAC bit set). self.logger.info( "Add 4 prefixes (all with SLAAC bit set) on leader {}".format( self.leader.name)) self.leader.add_prefix(prefix1, on_mesh=True, slaac=True, configure=True) self.leader.add_prefix(prefix2, on_mesh=True, slaac=True, configure=True) self.leader.add_prefix(prefix3, on_mesh=True, slaac=True, configure=True) self.leader.add_prefix(prefix4, on_mesh=True, slaac=True, configure=True) self.wait_for_completion(self.device_list) self.logger.info( "Verify that the sleepy child {} gets all 4 SLAAC addresses". format(self.child.name)) def check_addresses_on_child(): verify_address([self.child], prefix1) verify_address([self.child], prefix2) verify_address([self.child], prefix3) verify_address([self.child], prefix4) verify_within(check_addresses_on_child, WAIT_TIME)
def test03_Add_same_Prefix(self): # After prefix is seen on r1, add an address with same prefix on r1. self.r1.add_ip6_address_on_interface(IP6_ADDR_1, prefix_len=64) self.wait_for_completion(self.device_list) time.sleep(30) # Verify that the prefix is still seen on both nodes. verify_within(self.check_prefix, 5)
def test03_attach_joiner_to_commissioner(self): # Initiate the joiner attach process self.joiner.joiner_attach() def joiner_is_associated(): verify(is_associated(self.joiner)) verify_within(joiner_is_associated, WAIT_TIME)
def test03_verify_prefix_added(self): # Add slaac prefix on r1 self.r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True) self.wait_for_completion(self.device_list) # Verify that all nodes get the prefix and add the SLAAC address. # r1 should add 2 entries for prefix, 1 as origin:ncp (with rloc16 of r1), 2nd as origin:user (with rloc:0x0000) # r2 and fed1 should have 1 related prefix entry seen as origin:ncp (with rloc16 of r1) # Due to slaac=True prefix all the nodes should add related ip address. verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL)
def test04_verify_ncp_reset(self): # Reset r1 and verify that prefix and SLAAC address are re-added self.r1.reset_thread_radio() self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.assertEqual([ node.find_ip6_address_with_prefix(PREFIX) for node in self.all_nodes ], self.slaac_addrs)
def test02_Verify_Add_IPV6(self): # On `r2` add `IP6_ADDR_1` with prefix `IP6_PREFIX_1` # On `fed1` add `IP6_ADDR_2` with prefix `IP6_PREFIX_2` # On `sed2` add `IP6_ADDR_3` with prefix `IP6_PREFIX_3` self.r2.add_ip6_address_on_interface(IP6_ADDR_2, prefix_len=64) self.wait_for_completion(self.device_list) # Check the addresses and prefixes (wait time 60 seconds) verify_within(self.check_prefix, 5)
def test02_verify_neighbor_table(self): # Check that r1 and r2 are present in each other's neighbor table def check_neighbors_tables(): check_neighbor_table(self.r1, [self.r2]) check_neighbor_table(self.r2, [self.r1]) verify_within(check_neighbors_tables, WAIT_INTERVAL) self.assertTrue( self.r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) self.assertTrue( self.r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER)
def test03_verify_router_reset_and_recovery(self): # Reset r2 and check that everything recover correctly. Wait for it to be associated. self.r2.reset_thread_radio() self.wait_for_completion(self.device_list) self.logger.info( "verify after router {} reset and recovery it has leader(r1) {} in it's neighbor table" .format(self.r2.name, self.r1.name)) verify_within(self.check_r2_neighbor_table, WAIT_INTERVAL) self.assertTrue( self.r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) self.assertTrue( self.r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER)
def test04_Verify_New_Parent(self): # Verify that the `child` is now attached to `parent1` child_table = self.parent1.wpanctl( "get", "get " + wpan.WPAN_THREAD_CHILD_TABLE, 2) child_table = wpan_table_parser.parse_child_table_result(child_table) verify(len(child_table) == 1) # Finally verify that the `child` is removed from previous parent's child # table (which indicates that the `child` did indeed inform its previous # parent). verify_within(self.check_child_is_removed_from_parent2_table, 1)
def test02_Verify_Child_Mode(self): # Disable child supervision on all devices self.parent.set(wpan.WPAN_CHILD_SUPERVISION_INTERVAL, "0") self.child1.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, "0") self.child2.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, "0") # Verify Thread Device Mode on both children verify(int(self.child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) \ == DEVICE_MODE_END_DEVICE) verify(int(self.child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) \ == DEVICE_MODE_SLEEPY_END_DEVICE) verify_within(self.check_child_table, WAIT_INTERVAL)
def test12_verify_disabling_slaac_module_removes_slaac_address(self): # Ensure disabling SLAAC module removes previously added SLAAC addresses. self.r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True) verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.assertEqual([ node.find_ip6_address_with_prefix(PREFIX) for node in self.all_nodes ], self.slaac_addrs) for node in self.all_nodes: node.set(wpan.WPAN_OT_SLAAC_ENABLED, "false") verify_within(self.check_slaac_address_is_removed, WAIT_INTERVAL)
def test13_verify_enabling_slaac_module_adds_back_slaac_address(self): # Re-enable SLAAC support on NCP and verify addresses are re-added back. for node in self.all_nodes: node.set(wpan.WPAN_OT_SLAAC_ENABLED, "true") verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.assertEqual([ node.find_ip6_address_with_prefix(PREFIX) for node in self.all_nodes ], self.slaac_addrs) self.r1.remove_prefix(PREFIX) verify_within(self.check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)
def test04_reset_ncp_remove_prefix(self): # Reset r1 and verify that prefix and SLAAC address are re-added self.r1.reset_thread_radio() self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) # Remove the prefix on r1 and verify that the address and prefix are removed on all nodes. self.r1.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)
def test09_verify_removing_prefix_with_different_slaac_flag(self): # Remove the prefix on r2 and verify that related slaac prefix and address are removed self.r2.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) def check_slaac_address_is_removed(): wpan_util.verify_no_address(self.all_nodes, PREFIX) verify_within(check_slaac_address_is_removed, WAIT_INTERVAL) # Now remove the prefix on r1 and verify that all SLAAC prefix are removed self.r1.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)
def test02_verify_link(self): # Wait till first router has either established a link or # has a valid "next hop" towards all other routers. r1_rloc = int(self.routers[0].getprop(wpan.WPAN_THREAD_RLOC16), 16) def check_r1_router_table(): router_table = self.routers[0].get(wpan.WPAN_THREAD_ROUTER_TABLE) router_table = wpan_table_parser.parse_router_table_result( router_table) self.assertEqual(len(router_table), NUM_ROUTERS) for entry in router_table: verify(entry.rloc16 == r1_rloc or entry.is_link_established() or entry.next_hop != INVALID_ROUTER_ID) verify_within(check_r1_router_table, ROUTER_TABLE_WAIT_TIME)
def test04_Verify_Child_Mode_Change(self): # Change mode on both children (make child1 sleepy, and child2 non-sleepy) self.child1.set(wpan.WPAN_THREAD_DEVICE_MODE, str(DEVICE_MODE_SLEEPY_END_DEVICE)) verify(int(self.child1.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) \ == DEVICE_MODE_SLEEPY_END_DEVICE) self.child2.set(wpan.WPAN_THREAD_DEVICE_MODE, str(DEVICE_MODE_END_DEVICE)) verify(int(self.child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) \ == DEVICE_MODE_END_DEVICE) # Verify that the child table on parent is also updated verify_within(self.check_child_table, WAIT_INTERVAL)
def test04_verify_leader_reset_and_recovery(self): # Reset leader (i.e. r1) and check that everything recover correctly. self.r1.reset_thread_radio() self.wait_for_completion(self.device_list) self.logger.info( "verify after leader {} reset and recovery it has router(r2) {} in it's neighbor table" .format(self.r1.name, self.r2.name)) verify_within(self.check_r1_neighbor_table, WAIT_INTERVAL) self.assertTrue( self.r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) self.assertTrue( self.r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) self.logger.info("After leader reset verify r2's neighbor table too") verify_within(self.check_r2_neighbor_table, WAIT_INTERVAL)
def test03_detach_child(self): # Remove child from parent's allowlist self.parent.remove(wpan.WPAN_MAC_ALLOWLIST_ENTRIES, self.child.get(wpan.WPAN_EXT_ADDRESS)[1:-1]) self.wait_for_completion(self.device_list) # Enable supervision check on child, this ensures that child is detached soon. self.child.set(wpan.WPAN_CHILD_SUPERVISION_CHECK_TIMEOUT, str(CHILD_SUPERVISION_CHECK_TIMEOUT)) self.logger.info("verify child {} gets detached from parent {}".format( self.child.name, self.parent.name)) def check_child_is_detached(): verify(not is_associated(self.child)) verify_within(check_child_is_detached, WAIT_TIME)
def test03_verify_prefixes_on_r1_after_r2_leave(self): # Remove `r2` from the thread network. This should trigger all the prefixes added by it or its # child to timeout and be removed. self.logger.info("Get all nodes rloc16 before r2 leaves the network") r1_rloc16 = int(self.r1.get(wpan.WPAN_THREAD_RLOC16), 0) r2_rloc16 = int(self.r2.get(wpan.WPAN_THREAD_RLOC16), 0) sed1_rloc16 = int(self.sed1.get(wpan.WPAN_THREAD_RLOC16), 0) self.logger.info(" Remove r2 i.e. {} from the thread network".format( self.r2.name)) self.r2.leave() self.wait_for_completion(self.device_list) self.logger.info( "Wait for {}s for on-mesh prefix to be updated after r2's removal". format(PREFIX_SYNC_WAIT_AFTER_ROUTER_REMOVAL)) time.sleep(PREFIX_SYNC_WAIT_AFTER_ROUTER_REMOVAL) def check_prefixes_on_r1_after_r2_leave(): # Verify that entries added by r1 are still present self.logger.info( " verify prefix entries {} and {} added by r1 ({})" "are still present".format(prefix1, common_prefix, self.r1.name)) verify_prefix_with_rloc16([self.r1], prefix1, r1_rloc16, on_mesh=True, preferred=True, stable=True) verify_prefix_with_rloc16([self.r1], common_prefix, r1_rloc16, on_mesh=True, preferred=True, stable=False) self.logger.info( " verify prefix entries {}, {}, {} added by `r2` {} or `sed1` {} are removed" .format(prefix2, prefix3, common_prefix, self.r2.name, self.sed1.name)) verify_no_prefix_with_rloc16([self.r1], prefix2, r2_rloc16) verify_no_prefix_with_rloc16([self.r1], prefix3, sed1_rloc16) verify_no_prefix_with_rloc16([self.r1], common_prefix, r2_rloc16) verify_no_prefix_with_rloc16([self.r1], common_prefix, sed1_rloc16) verify_within(check_prefixes_on_r1_after_r2_leave, WAIT_TIME)
def test03_verify_reenabled_sc2_attaches_via_mle_announcement(self): # Now re-enable sc2 and verify that it does attach to router and is on channel 26 # sc2 would go through the ML Announce recovery. channel = self.network_data.channel self.sc2.set('Daemon:AutoAssociateAfterReset', 'true') self.sc2.reset_thread_radio() self.wait_for_completion(self.device_list) verify(int(self.sc2.get(wpan.WPAN_CHANNEL), 0) == channel) # Wait for 20s for sc2 to be attached/associated def check_c2_is_associated(): verify(is_associated(self.sc2)) verify_within(check_c2_is_associated, WAIT_TIME) # Check that sc2 is now on channel 26. verify(int(self.sc2.get(wpan.WPAN_CHANNEL), 0) == 26)
def test04_transmit_receive_secure_traffic(self): # Now router fully joins the network (set the network key), check all # secure traffic exchange between the nodes self.router.set(wpan.WPAN_KEY, self.parent.get(wpan.WPAN_KEY)[1:-1], binary_data=True) def check_router_is_associated(): verify(is_associated(self.router)) verify_within(check_router_is_associated, WAIT_TIME) self.parent.permit_join('0') self.transmit_receive_udp_message(self.router, self.parent, self.router.ip6_lla, self.parent.ip6_lla, src_port=SRC_PORT, port=INSECURE_PORT) self.router.permit_join('0') self.transmit_receive_udp_message(self.parent, self.router, self.parent.ip6_lla, self.router.ip6_lla, src_port=INSECURE_PORT, port=SRC_PORT)
def test06_remove_prefix_with_different_slaac_flag(self): # Remove prefix on r1. Verify addresses stay as before (as r2 still has # the same prefix) and related prefix entries belonging to r1 are removed. self.r1.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) # Remove the prefix on r2 and verify that the address and prefix are now removed on all nodes. self.r2.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL) # Add prefix on r1 without SLAAC flag, and on r2 with SLAAC flag # Note: without SLAAC flag no ipv6 address gets added on any node only the prefix gets added. self.r1.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=False) self.r2.add_prefix(PREFIX, stable=True, on_mesh=True, slaac=True) self.wait_for_completion(self.device_list) # Now r1 has 3 prefix entries(1 as origin:ncp (with rloc16 of r1),2nd as origin:user (with rloc:0x0000) # and 3rd as origin:ncp (with rloc16 of r2)). Similarly 3 such entries should be on r2. # On fed1 only 2 prefix entries should be present seen as origin:ncp (with rloc16 of r1) and # origin:ncp (with rloc16 of r2) # Verify due to slaac = True flag each node gets an ip address related to the prefix verify_within(self.check_prefix_and_slaac_address_are_added, WAIT_INTERVAL) self.logger.info("Remove the prefix on r2") self.r2.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) self.logger.info("verify slaac address is removed on all nodes") def check_slaac_address_is_removed(): wpan_util.verify_no_address(self.all_nodes, PREFIX) verify_within(check_slaac_address_is_removed, WAIT_INTERVAL) # Now remove the prefix on r1 and verify that all SLAAC prefix are removed self.r1.remove_prefix(PREFIX) self.wait_for_completion(self.device_list) verify_within(self.check_prefix_and_slaac_address_are_removed, WAIT_INTERVAL)