Skip to content

Commit 22a0375

Browse files
author
Arto Kinnunen
committed
Clear network data from lost children
In some cases thread network data may contain data from children who have changed parent but the network data still point to old parent. -When original parent comes back to network then is must clean such data. -If parent does not come back then network leader will detect parent loss and clean network data from the parent and its children.
1 parent ffd8517 commit 22a0375

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

source/6LoWPAN/Thread/thread_bootstrap.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,19 +170,19 @@ static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t
170170
else{
171171
tr_debug("Delete REED Neighbor");
172172
if (thread_is_router_addr(cur->short_adr)) {
173-
tr_debug("Router Free");
174-
thread_routing_remove_link(cur_interface, cur->short_adr);
173+
tr_debug("Router Free");
174+
thread_routing_remove_link(cur_interface, cur->short_adr);
175175
}
176176
}
177177
}
178178
else if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER)
179179
{
180-
tr_debug("Delete Router Neighbor");
180+
tr_debug("Delete Router Neighbor %x", cur->short_adr);
181181
if (thread_is_router_addr(cur->short_adr)) {
182-
tr_debug("Router Free");
182+
tr_debug("Router free");
183183
thread_routing_remove_link(cur_interface, cur->short_adr);
184184
} else if (thread_addr_is_child(mac_helper_mac16_address_get(cur_interface), cur->short_adr)) {
185-
tr_debug("Child Free");
185+
tr_debug("Child free");
186186
/* 16-bit neighbour cache entries are mesh addresses, so remain potentially valid even if an
187187
* MLE link fails. This is the only exception - if it was the link from us as a router to a
188188
* child. That means that device must be off the mesh (at that 16-bit address, at least).
@@ -1163,6 +1163,8 @@ void thread_tasklet(arm_event_s *event)
11631163
thread_border_router_publish(cur->id);
11641164
}
11651165
thread_router_bootstrap_address_change_notify_send(cur);
1166+
// Validate network data after a short period
1167+
thread_border_router_resubmit_timer_set(cur->id, 5);
11661168
break;
11671169
case THREAD_ATTACH_ROUTER_ID_GET_FAIL:
11681170
tr_debug_extra("Thread SM THREAD_ATTACH_ROUTER_ID_GET_FAIL");

source/6LoWPAN/Thread/thread_border_router_api.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,64 @@ static bool thread_border_router_local_network_data_prefix_match(thread_network_
297297
return true;
298298
}
299299

300+
static void thread_border_router_children_network_data_check_and_clean(uint8_t interface_id, uint16_t child_id)
301+
{
302+
uint8_t addr16_buf[2];
303+
304+
if (thread_is_router_addr(child_id)) {
305+
// Do not check routers
306+
return;
307+
}
308+
309+
common_write_16_bit(child_id, addr16_buf);
310+
311+
if (!mle_class_get_by_link_address(interface_id, addr16_buf, ADDR_802_15_4_SHORT)) {
312+
// Child is not our child => network data contains data from lost children, remove it
313+
tr_debug("Remove nwk data from lost child: %04x", child_id);
314+
thread_management_client_network_data_unregister(interface_id, child_id);
315+
}
316+
}
317+
318+
static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr)
319+
{
320+
321+
tr_debug("thread_border_router_lost_children_nwk_data_validate() %x", router_short_addr);
322+
if (!thread_is_router_addr(router_short_addr)) {
323+
// not validating children nwk data
324+
return;
325+
}
326+
327+
thread_network_data_cache_entry_t *network_data = &cur->thread_info->networkDataStorage;
328+
329+
ns_list_foreach(thread_network_data_prefix_cache_entry_t, curLP, &network_data->localPrefixList) {
330+
/* Go throgh all routes */
331+
ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) {
332+
if (thread_addr_is_child(router_short_addr, curRoute->routerID)) {
333+
// Router children found
334+
thread_border_router_children_network_data_check_and_clean(cur->id, curRoute->routerID);
335+
}
336+
}
337+
338+
/* Go through all BR's */
339+
ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) {
340+
if (thread_addr_is_child(router_short_addr, curBR->routerID)) {
341+
// Router children found
342+
thread_border_router_children_network_data_check_and_clean(cur->id, curBR->routerID);
343+
}
344+
}
345+
}
346+
347+
/* Go throgh all services */
348+
ns_list_foreach(thread_network_data_service_cache_entry_t, service, &network_data->service_list) {
349+
ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) {
350+
if (thread_addr_is_child(router_short_addr, server->router_id)) {
351+
// Router children found
352+
thread_border_router_children_network_data_check_and_clean(cur->id, server->router_id);
353+
}
354+
}
355+
}
356+
}
357+
300358
static bool thread_border_router_local_network_data_service_match(thread_network_local_data_cache_entry_t *local_data, thread_network_data_service_cache_entry_t *service, uint16_t router_id)
301359
{
302360
bool instance_found = false;
@@ -372,6 +430,8 @@ static bool thread_border_router_local_srv_data_in_network_data_check(protocol_i
372430
}
373431
}
374432

433+
thread_border_router_lost_children_nwk_data_validate(cur, router_id);
434+
375435
return true;
376436
}
377437

0 commit comments

Comments
 (0)