Skip to content

Commit 7610e91

Browse files
Child neighbor entry updates (#1550)
Cleanup any link we lose to something that looks like a child address. Refactored thread_neighbor_remove logic to thread_reset_neighbour_info, which is now called when MLE link to neighbour is lost or neighbour is removed due to transmission failure.
1 parent c727295 commit 7610e91

File tree

7 files changed

+67
-114
lines changed

7 files changed

+67
-114
lines changed

source/6LoWPAN/Thread/thread_bootstrap.c

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,6 @@ static void thread_bootsrap_network_join_start(struct protocol_interface_info_en
115115
static int8_t thread_child_keep_alive(int8_t interface_id, const uint8_t *mac64);
116116

117117

118-
int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child)
119-
{
120-
thread_dynamic_storage_child_info_clear(cur->id, child);
121-
122-
// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
123-
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) {
124-
tr_debug("Remove references to Child's RLOC16 from the Network Data");
125-
thread_management_client_network_data_unregister(cur->id, child->short_adr);
126-
}
127-
128-
// Clear all (sleepy) child registrations to multicast groups
129-
thread_child_mcast_entries_remove(cur, child->mac64);
130-
131-
return 0;
132-
}
133118

134119
static bool thread_interface_is_active(int8_t interface_id) {
135120
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
@@ -146,57 +131,7 @@ static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t
146131
if (!cur_interface) {
147132
return;
148133
}
149-
if (thread_info(cur_interface)->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE || thread_info(cur_interface)->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
150-
thread_parent_info_t *thread_endnode_parent = thread_info(cur_interface)->thread_endnode_parent;
151-
//Compare Parent
152-
if (thread_endnode_parent) {
153-
if (thread_endnode_parent->shortAddress == cur->short_adr) {
154-
tr_warn("End device lost Parent!\n");
155-
thread_bootstrap_connection_error(cur_interface->id, CON_PARENT_CONNECT_DOWN, NULL);
156-
}
157-
}
158-
}
159-
else {
160-
if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED)
161-
{
162-
thread_parent_info_t *thread_endnode_parent = thread_info(cur_interface)->thread_endnode_parent;
163-
if (thread_endnode_parent->shortAddress == cur->short_adr) {
164-
tr_warn("REED has lost Parent!\n");
165-
thread_routing_remove_link(cur_interface, cur->short_adr);
166-
if(cur_interface->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
167-
thread_bootstrap_connection_error(cur_interface->id, CON_PARENT_CONNECT_DOWN, NULL);
168-
}
169-
}
170-
else{
171-
tr_debug("Delete REED Neighbor");
172-
if (thread_is_router_addr(cur->short_adr)) {
173-
tr_debug("Router Free");
174-
thread_routing_remove_link(cur_interface, cur->short_adr);
175-
}
176-
}
177-
}
178-
else if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER)
179-
{
180-
tr_debug("Delete Router Neighbor %x", cur->short_adr);
181-
if (thread_is_router_addr(cur->short_adr)) {
182-
tr_debug("Router free");
183-
thread_routing_remove_link(cur_interface, cur->short_adr);
184-
} else if (thread_addr_is_child(mac_helper_mac16_address_get(cur_interface), cur->short_adr)) {
185-
tr_debug("Child free");
186-
/* 16-bit neighbour cache entries are mesh addresses, so remain potentially valid even if an
187-
* MLE link fails. This is the only exception - if it was the link from us as a router to a
188-
* child. That means that device must be off the mesh (at that 16-bit address, at least).
189-
* This will actually clear either a GC cache entry for a FTD or a registered entry
190-
* for a MTD.
191-
*/
192-
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr);
193-
thread_bootstrap_reset_child_info(cur_interface, cur);
194-
}
195-
}
196-
}
197-
198-
protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64);
199-
mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index);
134+
thread_reset_neighbour_info(cur_interface, cur);
200135
}
201136

202137

source/6LoWPAN/Thread/thread_common.c

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,36 +1837,27 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure
18371837
return;
18381838
}
18391839

1840-
if (thread_i_am_router(cur)) {
1841-
if (thread_addr_is_child(mac_helper_mac16_address_get(cur), neighbor->short_adr)) {
1842-
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1843-
return;
1844-
}
1845-
1846-
tr_debug("Free the Child node, mac16=%d", neighbor->short_adr);
1847-
thread_bootstrap_reset_child_info(cur, neighbor);
1848-
1849-
protocol_6lowpan_release_short_link_address_from_neighcache(cur, neighbor->short_adr);
1850-
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbor->mac64);
1851-
mac_helper_devicetable_remove(cur->mac_api, neighbor->attribute_index);
1852-
} else if (thread_is_router_addr(neighbor->short_adr)) {
1853-
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_ROUTER_TRANSMISSIONS) {
1854-
return;
1855-
}
1856-
1857-
tr_debug("Set link quality to neighbor router to zero...");
1858-
thread_routing_force_link_margin(cur, neighbor->short_adr, 0);
1859-
}
1860-
} else { // We are a Child
1861-
if (thread_check_is_this_my_parent(cur, neighbor)) {
1862-
if (accumulated_failures < THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1863-
return;
1864-
}
1865-
1866-
tr_debug("Consider the parent gone...");
1867-
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
1868-
}
1869-
}
1840+
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
1841+
thread_reset_neighbour_info(cur, neighbor);
1842+
}
1843+
}
1844+
1845+
/* Called when MLE link to neighbour lost, or ETX callback says link is bad */
1846+
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour)
1847+
{
1848+
thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent;
1849+
1850+
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) {
1851+
tr_warn("End device lost Parent!\n");
1852+
if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
1853+
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
1854+
}
1855+
}
1856+
1857+
thread_routing_remove_link(cur, neighbour->short_adr);
1858+
thread_router_bootstrap_reset_child_info(cur, neighbour);
1859+
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64);
1860+
mac_helper_devicetable_remove(cur->mac_api, neighbour->attribute_index);
18701861
}
18711862

18721863
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv)

source/6LoWPAN/Thread/thread_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ uint16_t thread_network_data_generate_stable_set(protocol_interface_info_entry_t
359359

360360
void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId);
361361
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv);
362+
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour);
362363

363364
void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur);
364365
thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64);

source/6LoWPAN/Thread/thread_router_bootstrap.c

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -947,26 +947,45 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t *
947947
return 0;
948948
}
949949

950-
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur)
950+
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child)
951951
{
952+
/* Cleanup occurs for /any/ link we lose to something that looks like a child address,
953+
* not just links that are /now/ our children.
954+
* Due to REED/partition transitions the address may not look like a current child address;
955+
* we could be holding a child entry for future repromotion to router with same ID.
956+
*/
957+
if (thread_is_router_addr(child->short_adr) || child->short_adr >= 0xfffe) {
958+
return -1;
959+
}
960+
tr_debug("Child free %x", child->short_adr);
961+
thread_dynamic_storage_child_info_clear(cur->id, child);
952962

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 */
963+
/* As we are losing a link to a child address, we can assume that if we have an IP neighbour cache
964+
* mapping to that address, it is no longer valid. We must have been their parent, and they must be
965+
* finding a new parent, and hence a new 16-bit address. (Losing a link to a router address would not
966+
* invalidate our IP->16-bit mapping.)
967+
*/
968+
protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->short_adr);
956969

957-
if (!cur->thread_info) {
958-
return;
970+
// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
971+
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) {
972+
tr_debug("Remove references to Child's RLOC16 from the Network Data");
973+
thread_management_client_network_data_unregister(cur->id, child->short_adr);
959974
}
960975

961-
if (cur->thread_info->routerShortAddress == 0xfffe) {
962-
return;
963-
}
976+
// Clear all (sleepy) child registrations to multicast groups
977+
thread_child_mcast_entries_remove(cur, child->mac64);
964978

965-
// Remove registered entries in IP neighbour cache
966-
ns_list_foreach_safe(ipv6_neighbour_t, neighbour, &cur->ipv6_neighbour_cache.list) {
967-
if (neighbour->type == IP_NEIGHBOUR_REGISTERED) {
968-
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour);
969-
}
979+
return 0;
980+
}
981+
982+
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur)
983+
{
984+
/* make sure that the child info (from previous partition if any)
985+
is cleared if no router address is got from leader */
986+
987+
if (!cur->thread_info) {
988+
return;
970989
}
971990

972991
// Remove mle neighbour entries for children in previous partition
@@ -975,11 +994,10 @@ void thread_router_bootstrap_child_information_clear(protocol_interface_info_ent
975994
return;
976995
}
977996
ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) {
978-
if (!thread_is_router_addr(table_entry->short_adr) && thread_router_addr_from_addr(table_entry->short_adr) == cur->thread_info->routerShortAddress) {
997+
if (table_entry->short_adr < 0xfffe && !thread_is_router_addr(table_entry->short_adr)) {
979998
mle_class_remove_entry(cur->id, table_entry);
980999
}
9811000
}
982-
9831001
}
9841002
static void thread_router_bootstrap_invalid_child_information_clear(protocol_interface_info_entry_t *cur, uint16_t router_rloc)
9851003
{
@@ -996,7 +1014,6 @@ static void thread_router_bootstrap_invalid_child_information_clear(protocol_int
9961014
if (table_entry->short_adr < 0xfffe &&
9971015
!thread_is_router_addr(table_entry->short_adr) &&
9981016
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);
10001017
mle_class_remove_entry(cur->id, table_entry);
10011018
}
10021019
}
@@ -2329,6 +2346,7 @@ static void thread_reed_advertisements_cb(void* arg)
23292346
if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED &&
23302347
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){
23312348
thread_reed_advertise(cur);
2349+
thread_router_bootstrap_child_information_clear(cur);
23322350
cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb, thread_reed_timeout_calculate(&cur->thread_info->routerSelectParameters) * 1000, cur);
23332351
}
23342352
}

source/6LoWPAN/Thread/thread_router_bootstrap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_e
4848
int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur);
4949

5050
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur);
51+
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child);
5152
uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur);
5253
void thread_router_bootstrap_child_id_handler(struct protocol_interface_info_entry *cur);
5354
void thread_router_bootstrap_child_id_reject(struct protocol_interface_info_entry *cur);
@@ -93,6 +94,7 @@ void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_
9394
#define thread_router_bootstrap_timer(cur, ticks)
9495
#define thread_router_bootstrap_random_upgrade_jitter() 0;
9596
#define thread_router_bootstrap_advertiment_analyze(cur, src_address, entry_temp, shortAddress)
97+
#define thread_router_bootstrap_reset_child_info(cur, child) 0
9698

9799
#define thread_router_bootstrap_multicast_forwarder_enable(cur, buf) NULL
98100
#define thread_router_bootstrap_anycast_address_register(cur)

test/nanostack/unittest/stub/thread_common_stub.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,6 @@ int thread_address_registration_primary_bbr_get(struct protocol_interface_info_e
393393
{
394394
return 0;
395395
}
396+
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour)
397+
{
398+
}

test/nanostack/unittest/stub/thread_router_bootstrap_stub.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,7 @@ void thread_router_bootstrap_network_data_distribute(protocol_interface_info_ent
154154
void thread_router_bootstrap_address_change_notify_send(protocol_interface_info_entry_t *cur)
155155
{
156156
}
157-
157+
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child)
158+
{
159+
return 0;
160+
}

0 commit comments

Comments
 (0)