Skip to content

Commit

Permalink
reset Dodag if global address is lost.
Browse files Browse the repository at this point in the history
If we lose the dodag_id address we need to restart Border router
  • Loading branch information
Mika Tervonen committed May 7, 2018
1 parent 0ec37a6 commit 51a498b
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 3 deletions.
22 changes: 20 additions & 2 deletions source/6LoWPAN/ws/ws_bbr_api.c
Expand Up @@ -41,6 +41,9 @@

#ifdef HAVE_WS

static uint8_t static_dodag_prefix[8] = {0xfd,0x00,0x61, 0x72, 0x6d};
static uint8_t static_dodag_id[16] = {0};

static void ws_bbr_rpl_root_activate(uint8_t *dodag_prefix, uint8_t *dodag_id)
{
tr_debug("RPL root Activate");
Expand All @@ -61,10 +64,18 @@ static void ws_bbr_rpl_root_activate(uint8_t *dodag_prefix, uint8_t *dodag_id)
};

rpl_data_init_root();

if (protocol_6lowpan_rpl_root_dodag) {
rpl_control_delete_dodag_root(protocol_6lowpan_rpl_domain, protocol_6lowpan_rpl_root_dodag);
protocol_6lowpan_rpl_root_dodag = NULL;
}

protocol_6lowpan_rpl_root_dodag = rpl_control_create_dodag_root(protocol_6lowpan_rpl_domain, RPL_INSTANCE_ID, dodag_id, &new_conf, new_conf.min_hop_rank_increase, RPL_GROUNDED | RPL_MODE_NON_STORING | RPL_DODAG_PREF(0));
if (!protocol_6lowpan_rpl_root_dodag) {
tr_err("RPL dodag init failed");
return;
}
memcpy(static_dodag_id,dodag_id,16);

// RPL memory limits set larger for Border router
rpl_control_set_memory_limits(64*1024, 0);
Expand All @@ -76,8 +87,6 @@ static void ws_bbr_rpl_root_activate(uint8_t *dodag_prefix, uint8_t *dodag_id)
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, NULL, 0, 0, 0xffffffff, false);
}

static uint8_t static_dodag_prefix[8] = {0xfd,0x00,0x61, 0x72, 0x6d};

static void ws_bbr_root_start(protocol_interface_info_entry_t *cur)
{
uint8_t *bbr_prefix_ptr = NULL;
Expand Down Expand Up @@ -119,6 +128,15 @@ void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds
return;
}

if (protocol_6lowpan_rpl_root_dodag){
// Border router is active
if (0 != protocol_interface_address_compare(static_dodag_id)) {
// Dodag has become invalid need to delete
tr_info("RPL dodag not valid anymore");
rpl_control_delete_dodag_root(protocol_6lowpan_rpl_domain, protocol_6lowpan_rpl_root_dodag);
protocol_6lowpan_rpl_root_dodag = NULL;
}
}
if (!protocol_6lowpan_rpl_root_dodag) {
// RPL configured
// 1. Wait for backend connection
Expand Down
2 changes: 1 addition & 1 deletion source/RPL/rpl_control.c
Expand Up @@ -455,7 +455,7 @@ void rpl_control_delete_dodag_root(rpl_domain_t *domain, rpl_dodag_t *dodag)
{
(void)domain;

rpl_delete_dodag(dodag);
rpl_delete_dodag_root(dodag);
}

void rpl_control_update_dodag_route(rpl_dodag_t *dodag, const uint8_t *prefix, uint8_t prefix_len, uint8_t flags, uint32_t lifetime, bool age)
Expand Down
23 changes: 23 additions & 0 deletions source/RPL/rpl_upward.c
Expand Up @@ -542,6 +542,14 @@ void rpl_delete_dodag_version(rpl_dodag_version_t *version)
rpl_dodag_t *dodag = version->dodag;
rpl_instance_t *instance = dodag->instance;

if (instance->current_dodag_version == version) {
// Don't call rpl_instance_set_dodag_version(NULL) - that would pre-empt parent reselection,
// triggering poison immediately.
// Give parent selection a chance to select another version (but will it have any info on-hand?)
instance->current_dodag_version = NULL;
rpl_instance_trigger_parent_selection(instance, 5);
}

ns_list_foreach_safe(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) {
if (neighbour->dodag_version == version) {
rpl_delete_neighbour(instance, neighbour);
Expand Down Expand Up @@ -649,6 +657,21 @@ void rpl_delete_dodag(rpl_dodag_t *dodag)
rpl_free(dodag, sizeof(*dodag));
}

void rpl_delete_dodag_root(rpl_dodag_t *dodag)
{
// This should trigger immediate poison
rpl_instance_set_dodag_version(dodag->instance, NULL, RPL_RANK_INFINITE);
// Deleting DODAG is not ideal - we will just pick up adverts from our
// former children, and recreate, possibly violating the MaxRankIncrease.
// Should retain DODAG version info and just unset root flag, which will
// limit what happens when we hear adverts.
// Problem is rpl_control_create_dodag_root which can't handle the
// case where DODAG already exists. This would always be a problem if
// we'd heard adverts in between delete and create, but would be an instant
// problem without this delete. Need to fix.
rpl_delete_dodag(dodag);
}

/* Convert RPL configuration to generic trickle parameters. Returns true if
* the value in the generic object has changed.
*/
Expand Down
1 change: 1 addition & 0 deletions source/RPL/rpl_upward.h
Expand Up @@ -88,6 +88,7 @@ void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds);
rpl_dodag_t *rpl_lookup_dodag(const rpl_instance_t *instance, const uint8_t *dodagid);
rpl_dodag_t *rpl_create_dodag(rpl_instance_t *instance, const uint8_t *dodagid, uint8_t g_mop_prf);
void rpl_delete_dodag(rpl_dodag_t *dodag);
void rpl_delete_dodag_root(rpl_dodag_t *dodag);
uint8_t rpl_dodag_mop(const rpl_dodag_t *dodag);
void rpl_dodag_set_root(rpl_dodag_t *dodag, bool root);
#ifdef HAVE_RPL_ROOT
Expand Down
3 changes: 3 additions & 0 deletions test/nanostack/unittest/stub/rpl_upward_stub.c
Expand Up @@ -238,6 +238,9 @@ rpl_dodag_version_t *rpl_create_dodag_version(rpl_dodag_t *dodag, uint8_t versio
void rpl_delete_dodag_version(rpl_dodag_version_t *version)
{
}
void rpl_delete_dodag_root(rpl_dodag_t *dodag)
{
}

bool rpl_dodag_version_is_current(const rpl_dodag_version_t *version)
{
Expand Down

0 comments on commit 51a498b

Please sign in to comment.