Skip to content

Commit c727295

Browse files
cleared neighbours with child address that are not ours (ARMmbed#1549)
when a new router id is received from the leader upon merging to a new partition.
1 parent 80b4d72 commit c727295

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

source/6LoWPAN/Thread/thread_router_bootstrap.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,11 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t *
949949

950950
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur)
951951
{
952+
953+
/*the default routerShortAddress if nothing is requested is 0xfffe so eliminate this case
954+
Also make sure that the child info (from previous partition if any)
955+
is cleared if no router address is got from leader */
956+
952957
if (!cur->thread_info) {
953958
return;
954959
}
@@ -976,6 +981,26 @@ void thread_router_bootstrap_child_information_clear(protocol_interface_info_ent
976981
}
977982

978983
}
984+
static void thread_router_bootstrap_invalid_child_information_clear(protocol_interface_info_entry_t *cur, uint16_t router_rloc)
985+
{
986+
987+
tr_debug("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc);
988+
989+
mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id);
990+
if (!entry_list) {
991+
return;
992+
}
993+
994+
// scrub neighbours with child addresses that are not ours
995+
ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) {
996+
if (table_entry->short_adr < 0xfffe &&
997+
!thread_is_router_addr(table_entry->short_adr) &&
998+
thread_router_addr_from_addr(table_entry->short_adr) != router_rloc) {
999+
ipv6_neighbour_delete_registered_by_eui64(&cur->ipv6_neighbour_cache, table_entry->mac64);
1000+
mle_class_remove_entry(cur->id, table_entry);
1001+
}
1002+
}
1003+
}
9791004

9801005
static void thread_bootstrap_client_router_id_cb(int8_t interface_id, int8_t status, uint16_t router_rloc, const uint8_t router_mask_ptr[9])
9811006
{
@@ -1011,13 +1036,8 @@ static void thread_bootstrap_client_router_id_cb(int8_t interface_id, int8_t sta
10111036
parent_router_id = cur->thread_info->thread_endnode_parent->router_id;
10121037
}
10131038

1014-
tr_info("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc);
1015-
/*the default routerShortAddress if nothing is requested is 0xfffe so eliminate this case
1016-
Also make sure that the child info (from previous partition if any)
1017-
is cleared if the router address requested is not what is got from leader */
1018-
if ( cur->thread_info->routerShortAddress != router_rloc) {
1019-
thread_router_bootstrap_child_information_clear(cur);
1020-
}
1039+
thread_router_bootstrap_invalid_child_information_clear(cur,router_rloc);
1040+
10211041
// Release network data from old address
10221042
cur->thread_info->localServerDataBase.release_old_address = true;
10231043

source/ipv6_stack/ipv6_routing_table.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,15 @@ void ipv6_neighbour_invalidate_ll_addr(ipv6_neighbour_cache_t *cache, addrtype_t
401401
}
402402
}
403403

404+
void ipv6_neighbour_delete_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64)
405+
{
406+
ns_list_foreach_safe(ipv6_neighbour_t, cur, &cache->list) {
407+
if (cur->type != IP_NEIGHBOUR_GARBAGE_COLLECTIBLE && memcmp(ipv6_neighbour_eui64(cache, cur), eui64, 8) == 0) {
408+
ipv6_neighbour_entry_remove(cache, cur);
409+
}
410+
}
411+
}
412+
404413
void ipv6_neighbour_set_state(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, ip_neighbour_cache_state_t state)
405414
{
406415
if (!ipv6_neighbour_state_is_probably_reachable(entry->state) &&

source/ipv6_stack/ipv6_routing_table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ extern bool ipv6_neighbour_is_probably_reachable(ipv6_neighbour_cache_t *cache,
154154
extern bool ipv6_neighbour_addr_is_probably_reachable(ipv6_neighbour_cache_t *cache, const uint8_t *address);
155155
extern bool ipv6_neighbour_ll_addr_match(const ipv6_neighbour_t *entry, addrtype_t ll_type, const uint8_t *ll_address);
156156
extern void ipv6_neighbour_invalidate_ll_addr(ipv6_neighbour_cache_t *cache, addrtype_t ll_type, const uint8_t *ll_address);
157+
extern void ipv6_neighbour_delete_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64);
157158
extern void ipv6_neighbour_entry_update_unsolicited(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, addrtype_t type, const uint8_t *ll_address/*, bool tentative*/);
158159
extern ipv6_neighbour_t *ipv6_neighbour_update_unsolicited(ipv6_neighbour_cache_t *cache, const uint8_t *ip_address, addrtype_t ll_type, const uint8_t *ll_address);
159160
extern void ipv6_neighbour_reachability_confirmation(const uint8_t ip_address[__static 16], int8_t interface_id);

0 commit comments

Comments
 (0)