Skip to content

Commit

Permalink
Clear network data from lost children
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Arto Kinnunen committed Dec 21, 2017
1 parent ffd8517 commit 22a0375
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
12 changes: 7 additions & 5 deletions source/6LoWPAN/Thread/thread_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,19 @@ static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t
else{
tr_debug("Delete REED Neighbor");
if (thread_is_router_addr(cur->short_adr)) {
tr_debug("Router Free");
thread_routing_remove_link(cur_interface, cur->short_adr);
tr_debug("Router Free");
thread_routing_remove_link(cur_interface, cur->short_adr);
}
}
}
else if (thread_info(cur_interface)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER)
{
tr_debug("Delete Router Neighbor");
tr_debug("Delete Router Neighbor %x", cur->short_adr);
if (thread_is_router_addr(cur->short_adr)) {
tr_debug("Router Free");
tr_debug("Router free");
thread_routing_remove_link(cur_interface, cur->short_adr);
} else if (thread_addr_is_child(mac_helper_mac16_address_get(cur_interface), cur->short_adr)) {
tr_debug("Child Free");
tr_debug("Child free");
/* 16-bit neighbour cache entries are mesh addresses, so remain potentially valid even if an
* MLE link fails. This is the only exception - if it was the link from us as a router to a
* child. That means that device must be off the mesh (at that 16-bit address, at least).
Expand Down Expand Up @@ -1163,6 +1163,8 @@ void thread_tasklet(arm_event_s *event)
thread_border_router_publish(cur->id);
}
thread_router_bootstrap_address_change_notify_send(cur);
// Validate network data after a short period
thread_border_router_resubmit_timer_set(cur->id, 5);
break;
case THREAD_ATTACH_ROUTER_ID_GET_FAIL:
tr_debug_extra("Thread SM THREAD_ATTACH_ROUTER_ID_GET_FAIL");
Expand Down
60 changes: 60 additions & 0 deletions source/6LoWPAN/Thread/thread_border_router_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,64 @@ static bool thread_border_router_local_network_data_prefix_match(thread_network_
return true;
}

static void thread_border_router_children_network_data_check_and_clean(uint8_t interface_id, uint16_t child_id)
{
uint8_t addr16_buf[2];

if (thread_is_router_addr(child_id)) {
// Do not check routers
return;
}

common_write_16_bit(child_id, addr16_buf);

if (!mle_class_get_by_link_address(interface_id, addr16_buf, ADDR_802_15_4_SHORT)) {
// Child is not our child => network data contains data from lost children, remove it
tr_debug("Remove nwk data from lost child: %04x", child_id);
thread_management_client_network_data_unregister(interface_id, child_id);
}
}

static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr)
{

tr_debug("thread_border_router_lost_children_nwk_data_validate() %x", router_short_addr);
if (!thread_is_router_addr(router_short_addr)) {
// not validating children nwk data
return;
}

thread_network_data_cache_entry_t *network_data = &cur->thread_info->networkDataStorage;

ns_list_foreach(thread_network_data_prefix_cache_entry_t, curLP, &network_data->localPrefixList) {
/* Go throgh all routes */
ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) {
if (thread_addr_is_child(router_short_addr, curRoute->routerID)) {
// Router children found
thread_border_router_children_network_data_check_and_clean(cur->id, curRoute->routerID);
}
}

/* Go through all BR's */
ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) {
if (thread_addr_is_child(router_short_addr, curBR->routerID)) {
// Router children found
thread_border_router_children_network_data_check_and_clean(cur->id, curBR->routerID);
}
}
}

/* Go throgh all services */
ns_list_foreach(thread_network_data_service_cache_entry_t, service, &network_data->service_list) {
ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) {
if (thread_addr_is_child(router_short_addr, server->router_id)) {
// Router children found
thread_border_router_children_network_data_check_and_clean(cur->id, server->router_id);
}
}
}
}

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)
{
bool instance_found = false;
Expand Down Expand Up @@ -372,6 +430,8 @@ static bool thread_border_router_local_srv_data_in_network_data_check(protocol_i
}
}

thread_border_router_lost_children_nwk_data_validate(cur, router_id);

return true;
}

Expand Down

0 comments on commit 22a0375

Please sign in to comment.