Skip to content

Commit a3bcc2d

Browse files
author
Mika Tervonen
committed
Removed the PAN version change requirement from routers
Added configuration for border router to disable periodic version number change Added for RPL - Minimum DAO interval configuration to force timeouts to happen in 2 hours - function to trigger DAO refresh Bootstrap If routers dont see the version increase they trigger RPL DAO
1 parent bc919d8 commit a3bcc2d

16 files changed

+149
-51
lines changed

nanostack/ws_bbr_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
5252
#define BBR_GUA_ROUTE 0x0002 /**< More specific route is added for GUA prefix */
5353
#define BBR_BB_WAIT 0x0004 /**< Wait backbone availability before starting Wi-SUN network */
5454
#define BBR_DEFAULT_ROUTE 0x0008 /**< Add default route parameter to DIO */
55+
#define BBR_REQUIRE_DAO_REFRESH 0x0010 /**< Do not increment PAN version number when active forces DAO update from nodes*/
5556

5657
/**
5758
* Configure border router features.

source/6LoWPAN/ws/ws_bbr_api.c

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static uint8_t current_instance_id = RPL_INSTANCE_ID;
6161
*/
6262
static int8_t backbone_interface_id = -1; // BBR backbone information
6363
static uint16_t configuration = 0;
64+
static uint32_t pan_version_timer = 0;
6465

6566
static uint8_t static_dodag_prefix[8] = {0xfd, 0x00, 0x72, 0x83, 0x7e};
6667
static uint8_t static_dodag_id_prefix[8] = {0xfd, 0x00, 0x61, 0x72, 0x6d};
@@ -532,6 +533,22 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
532533
}
533534
}
534535
}
536+
void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur)
537+
{
538+
if (!cur) {
539+
return;
540+
}
541+
tr_debug("Border router version number update");
542+
if (configuration & BBR_REQUIRE_DAO_REFRESH) {
543+
// Version number is not periodically increased forcing nodes to check Border router availability using DAO
544+
pan_version_timer = 0;
545+
} else {
546+
pan_version_timer = ws_common_version_timeout_get(cur->ws_info->network_size_config) / PAN_VERSION_CHANGE_INTERVAL;
547+
}
548+
cur->ws_info->pan_information.pan_version++;
549+
// Inconsistent for border router to make information distribute faster
550+
ws_bootstrap_configuration_trickle_reset(cur);
551+
}
535552

536553
void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
537554
{
@@ -574,18 +591,21 @@ void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds
574591
}
575592
// Normal BBR operation
576593
if (protocol_6lowpan_rpl_root_dodag) {
577-
if (cur->ws_info->pan_version_timer > seconds) {
578-
cur->ws_info->pan_version_timer -= seconds;
579-
} else {
580-
// PAN version number update
581-
tr_debug("Border router version number update");
582-
cur->ws_info->pan_version_timer = ws_common_version_lifetime_get(cur->ws_info->network_size_config);
583-
cur->ws_info->pan_information.pan_version++;
584-
// Inconsistent for border router to make information distribute faster
585-
ws_bootstrap_configuration_trickle_reset(cur);
586-
587-
if (cur->ws_info->network_size_config == NETWORK_SIZE_AUTOMATIC) {
588-
ws_common_network_size_configure(cur, cur->ws_info->pan_information.pan_size);
594+
/*
595+
* PAN version change is one way to enable nodes to detect the border router availability
596+
* if this is not done periodically devices need to have other means to detect border router condiftion
597+
*
598+
* If devices do not see version change they need to send DAO to border router before PAN timeout
599+
*
600+
* The update frequency should be related to PAN timeout and happen for example 4 times.
601+
*/
602+
if (pan_version_timer > 0) {
603+
if (pan_version_timer > seconds) {
604+
pan_version_timer -= seconds;
605+
} else {
606+
// PAN version number update
607+
pan_version_timer = 0;
608+
ws_bbr_pan_version_increase(cur);
589609
}
590610
}
591611
if (cur->ws_info->rpl_version_timer > seconds) {
@@ -723,6 +743,9 @@ int ws_bbr_node_access_revoke_start(int8_t interface_id)
723743
{
724744
(void) interface_id;
725745
#ifdef HAVE_WS_BORDER_ROUTER
746+
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
747+
748+
ws_bbr_pan_version_increase(cur);
726749
return ws_pae_controller_node_access_revoke_start(interface_id);
727750
#else
728751
return -1;

source/6LoWPAN/ws/ws_bbr_api_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ extern uint16_t test_pan_size_override;
2525

2626
void ws_bbr_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
2727

28+
void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur);
29+
2830
uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur);
2931

3032
void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase);
@@ -35,6 +37,7 @@ bool ws_bbr_ready_to_start(protocol_interface_info_entry_t *cur);
3537
#else
3638

3739
#define ws_bbr_seconds_timer( cur, seconds)
40+
#define ws_bbr_pan_version_increase(cur)
3841
#define ws_bbr_pan_size(cur) 0
3942
#define ws_bbr_rpl_config( cur, imin, doubling, redundancy, dag_max_rank_increase, min_hop_rank_increase)
4043
#define ws_bbr_ready_to_start(cur) true

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
12781278
tr_info("Updated PAN configuration own:%d, heard:%d", cur->ws_info->pan_information.pan_version, pan_version);
12791279

12801280
// restart PAN version timer
1281-
cur->ws_info->pan_version_timeout_timer = ws_common_version_timeout_get(cur->ws_info->network_size_config);
1281+
cur->ws_info->pan_timeout_timer = ws_common_version_timeout_get(cur->ws_info->network_size_config);
12821282
cur->ws_info->pan_information.pan_version = pan_version;
12831283

12841284
ws_pae_controller_gtk_hash_update(cur, gtkhash_ptr);
@@ -2017,6 +2017,10 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
20172017
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->network_name);
20182018
// Network key is valid
20192019
ws_pae_controller_nw_key_valid(cur);
2020+
2021+
// After successful DAO ACK connection to border router is verified
2022+
cur->ws_info->pan_timeout_timer = ws_common_version_timeout_get(cur->ws_info->network_size_config);
2023+
20202024
}
20212025

20222026
ws_set_fhss_hop(cur);
@@ -2274,6 +2278,9 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
22742278
rpl_control_set_memory_limits(WS_NODE_RPL_SOFT_MEM_LIMIT, WS_NODE_RPL_HARD_MEM_LIMIT);
22752279
}
22762280

2281+
// Set the minimum target refresh to sen DAO registrations before pan timeout
2282+
rpl_control_set_minimum_dao_target_refresh(WS_RPL_DAO_MAX_TIMOUT);
2283+
22772284
cur->ws_info->rpl_state = 0xff; // Set invalid state and learn from event
22782285
}
22792286

@@ -2307,7 +2314,8 @@ static void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur)
23072314

23082315
static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur)
23092316
{
2310-
cur->ws_info->pan_version_timer = 1;
2317+
(void)cur;
2318+
ws_bbr_pan_version_increase(cur);
23112319
}
23122320

23132321
// Start network scan
@@ -2319,7 +2327,7 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
23192327
ws_bootstrap_state_change(cur, ER_ACTIVE_SCAN);
23202328
cur->nwk_nd_re_scan_count = 0;
23212329
cur->ws_info->configuration_learned = false;
2322-
cur->ws_info->pan_version_timeout_timer = 0;
2330+
cur->ws_info->pan_timeout_timer = 0;
23232331

23242332
// Clear learned neighbours
23252333
ws_bootstrap_neighbor_list_clean(cur);
@@ -2471,6 +2479,11 @@ static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur)
24712479
// Set timeout for check to 30 -60 seconds
24722480
cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(WS_RPL_DIS_INITIAL_TIMEOUT / 2, WS_RPL_DIS_INITIAL_TIMEOUT);
24732481
}
2482+
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
2483+
* Router for an interval of PAN_TIMEOUT, a node MUST assume failure of the PAN Border Router and MUST
2484+
* Transition to Join State 1
2485+
*/
2486+
cur->ws_info->pan_timeout_timer = ws_common_version_timeout_get(cur->ws_info->network_size_config);
24742487
}
24752488

24762489
/*
@@ -2685,6 +2698,9 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
26852698
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
26862699
cur->mac_parameters->mac_default_key_index = 0;
26872700

2701+
// Clear parent blacklist
2702+
blacklist_clear();
2703+
26882704
// All trickle timers stopped to allow entry from any state
26892705
cur->ws_info->trickle_pa_running = false;
26902706
cur->ws_info->trickle_pc_running = false;
@@ -2715,7 +2731,7 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
27152731

27162732
uint8_t *gtkhash = ws_pae_controller_gtk_hash_ptr_get(cur);
27172733
ws_llc_set_gtkhash(cur, gtkhash);
2718-
cur->ws_info->pan_version_timer = ws_common_version_lifetime_get(cur->ws_info->network_size_config);
2734+
ws_bbr_pan_version_increase(cur);
27192735

27202736
// Set default parameters for FHSS when starting a discovery
27212737
ws_fhss_border_router_configure(cur);
@@ -3018,12 +3034,23 @@ void ws_bootstrap_trickle_timer(protocol_interface_info_entry_t *cur, uint16_t t
30183034

30193035
void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds)
30203036
{
3021-
if (cur->ws_info->pan_version_timeout_timer) {
3037+
/* Border router keep alive check
3038+
*/
3039+
if (cur->ws_info->pan_timeout_timer) {
30223040
// PAN version timer running
3023-
if (cur->ws_info->pan_version_timeout_timer > seconds) {
3024-
cur->ws_info->pan_version_timeout_timer -= seconds;
3041+
if (cur->ws_info->pan_timeout_timer > seconds) {
3042+
cur->ws_info->pan_timeout_timer -= seconds;
3043+
if (cur->ws_info->pan_timeout_timer < ws_common_version_timeout_get(cur->ws_info->network_size_config) / 10) {
3044+
/* pan timeout is closing need to verify that DAO is tested before the pan times out.
3045+
This will give some extra time for RPL to find better parents.
3046+
Border router liveliness can be checked from version number change or from successful DAO registrations
3047+
in this case there has not been any version number changes during this PAN lifetime.
3048+
*/
3049+
rpl_control_dao_timeout(cur->rpl_domain, 20);
3050+
}
30253051
} else {
30263052
// Border router has timed out
3053+
cur->ws_info->pan_timeout_timer = 0;
30273054
tr_warn("Border router has timed out");
30283055
ws_bootstrap_event_discovery_start(cur);
30293056
}

source/6LoWPAN/ws/ws_common.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -456,21 +456,6 @@ bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, con
456456
return true;
457457
}
458458

459-
uint32_t ws_common_version_lifetime_get(uint8_t config)
460-
{
461-
uint32_t lifetime;
462-
if (config == NETWORK_SIZE_SMALL || config == NETWORK_SIZE_CERTIFICATE) {
463-
lifetime = PAN_VERSION_SMALL_NETWORK_LIFETIME;
464-
} else if (config == NETWORK_SIZE_MEDIUM) {
465-
lifetime = PAN_VERSION_MEDIUM_NETWORK_LIFETIME;
466-
} else {
467-
lifetime = PAN_VERSION_LARGE_NETWORK_LIFETIME;
468-
}
469-
470-
return lifetime;
471-
472-
}
473-
474459
uint32_t ws_common_version_timeout_get(uint8_t config)
475460
{
476461
uint32_t lifetime;

source/6LoWPAN/ws/ws_common.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ typedef struct ws_info_s {
8989
parent_info_list_t parent_list_free;
9090
parent_info_list_t parent_list_reserved;
9191
uint16_t rpl_version_timer; /**< RPL version update timeout */
92-
uint32_t pan_version_timer; /**< border router version update timeout */
93-
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
92+
uint32_t pan_timeout_timer; /**< routers will fallback to previous state after this */
9493
uint32_t pan_config_sol_max_timeout;
9594
uint8_t gtkhash[32];
9695
bool configuration_learned: 1;
@@ -145,9 +144,6 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *cur,
145144

146145
bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64);
147146

148-
149-
uint32_t ws_common_version_lifetime_get(uint8_t config);
150-
151147
uint32_t ws_common_version_timeout_get(uint8_t config);
152148

153149
#define ws_info(cur) ((cur)->ws_info)

source/6LoWPAN/ws/ws_config.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@
3737
#define WS_CERTIFICATE_RPL_MIN_HOP_RANK_INCREASE 128
3838
#define WS_CERTIFICATE_RPL_MAX_HOP_RANK_INCREASE 0
3939

40+
/*
41+
* RPL DAO timeout maximum value. This will force DAO timeout to happen before this time
42+
*/
43+
#define WS_RPL_DAO_MAX_TIMOUT (3600*2)
44+
4045
/* Border router version change interval
4146
*
42-
* Minimum interval at which a Border Router shall increment its PAN Version value.
47+
* Amount of version increases border router makes during PAN_TIMEOUT time
4348
*/
4449

45-
#define PAN_VERSION_SMALL_NETWORK_LIFETIME 4*60
46-
#define PAN_VERSION_MEDIUM_NETWORK_LIFETIME 15*60
47-
#define PAN_VERSION_LARGE_NETWORK_LIFETIME 30*60 //30min
50+
#define PAN_VERSION_CHANGE_INTERVAL 3
4851

4952
// RPL version number update intervall
5053
// after restart version numbers are increased faster and then slowed down when network is stable

source/RPL/rpl_control.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,10 @@ void rpl_control_set_dao_retry_count(uint8_t count)
185185
{
186186
rpl_policy_set_dao_retry_count(count);
187187
}
188-
188+
void rpl_control_set_minimum_dao_target_refresh(uint16_t seconds)
189+
{
190+
rpl_policy_set_minimum_dao_target_refresh(seconds);
191+
}
189192
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
190193
{
191194
rpl_policy_set_initial_dao_ack_wait(timeout_in_ms);
@@ -673,6 +676,14 @@ void rpl_control_force_leaf(rpl_domain_t *domain, bool leaf)
673676
}
674677
}
675678
}
679+
680+
void rpl_control_dao_timeout(rpl_domain_t *domain, uint16_t seconds)
681+
{
682+
ns_list_foreach(rpl_instance_t, instance, &domain->instances) {
683+
rpl_instance_dao_timeout(instance, seconds);
684+
}
685+
}
686+
676687
void rpl_control_process_routes(rpl_domain_t *domain, bool process_routes)
677688
{
678689
domain->process_routes = process_routes;

source/RPL/rpl_control.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ void rpl_control_process_routes(rpl_domain_t *domain, bool process_routes);
145145
/* Manually send poison on all existing instances a few times */
146146
void rpl_control_poison(rpl_domain_t *domain, uint8_t poison_count);
147147

148+
/* force DAO to verify connections before given time*/
149+
void rpl_control_dao_timeout(rpl_domain_t *domain, uint16_t seconds);
150+
148151
/* APIs to create domains and map them to interfaces */
149152
rpl_domain_t *rpl_control_create_domain(void);
150153
void rpl_control_delete_domain(rpl_domain_t *domain);
@@ -171,6 +174,7 @@ bool rpl_control_find_worst_neighbor(struct protocol_interface_info_entry *inter
171174
void rpl_control_request_parent_link_confirmation(bool requested);
172175
void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_count);
173176
void rpl_control_set_dao_retry_count(uint8_t count);
177+
void rpl_control_set_minimum_dao_target_refresh(uint16_t seconds);
174178
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms);
175179
void rpl_control_set_mrhof_parent_set_size(uint16_t parent_set_size);
176180
void rpl_control_register_address(struct protocol_interface_info_entry *interface, const uint8_t addr[16]);

source/RPL/rpl_downward.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ static void rpl_downward_topo_sort_invalidate(rpl_instance_t *instance);
109109

110110
#define DEFAULT_DAO_DELAY 10 /* *100ms ticks = 1s */
111111

112-
//#define MINIMUM_DAO_TARGET_REFRESH (5*60) /* seconds */
113-
114112
/* Bit <n> of the PC mask */
115113
#define PCBIT(n) (UINT8_C(0x80) >> (n))
116114

@@ -1603,11 +1601,10 @@ void rpl_instance_dao_acked(rpl_instance_t *instance, const uint8_t src[16], int
16031601
} else {
16041602
t = 0xFFFFFFFF;
16051603
}
1606-
#ifdef MINIMUM_DAO_TARGET_REFRESH
1607-
if (t > MINIMUM_DAO_TARGET_REFRESH) {
1608-
t = randLIB_randomise_base(MINIMUM_DAO_TARGET_REFRESH, 0x7333, 0x8CCD); /* +/- 10% */
1604+
if (rpl_policy_minimum_dao_target_refresh() && t > rpl_policy_minimum_dao_target_refresh()) {
1605+
// set the minimum target refresh time ranging from 25% to 10% below the value
1606+
t = randLIB_randomise_base(rpl_policy_minimum_dao_target_refresh(), 0x6000, 0x7333);
16091607
}
1610-
#endif
16111608
target->info.non_root.refresh_timer = t;
16121609
tr_debug("set rfr to %"PRIu32, t);
16131610
}
@@ -1639,6 +1636,21 @@ void rpl_instance_dao_request(struct rpl_instance *instance, struct rpl_neighbou
16391636
rpl_instance_dao_trigger(instance, 0);
16401637
}
16411638

1639+
void rpl_instance_dao_timeout(struct rpl_instance *instance, uint16_t seconds)
1640+
{
1641+
// Forces DAO timeout to happen before given time distributed in given time
1642+
ns_list_foreach(rpl_dao_target_t, target, &instance->dao_targets) {
1643+
if (!target->published || target->info.non_root.refresh_timer == 0) {
1644+
continue;
1645+
}
1646+
if (target->info.non_root.refresh_timer < seconds) {
1647+
continue;
1648+
}
1649+
// Shorten the timeout
1650+
target->info.non_root.refresh_timer = randLIB_get_random_in_range(1, seconds);
1651+
}
1652+
}
1653+
16421654

16431655
void rpl_downward_dao_slow_timer(rpl_instance_t *instance, uint16_t seconds)
16441656
{

source/RPL/rpl_downward.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void rpl_instance_delete_published_dao_target(struct rpl_instance *instance, con
3838
struct rpl_dao_target *rpl_instance_match_dao_target(struct rpl_instance *instance, const uint8_t *prefix, uint8_t prefix_len);
3939

4040
void rpl_instance_dao_request(struct rpl_instance *instance, struct rpl_neighbour *neighbour);
41+
void rpl_instance_dao_timeout(struct rpl_instance *instance, uint16_t seconds);
4142
void rpl_instance_dao_trigger(struct rpl_instance *instance, uint16_t delay);
4243
void rpl_instance_dao_acked(struct rpl_instance *instance, const uint8_t src[16], int8_t interface_id, uint8_t dao_sequence, uint8_t status);
4344
void rpl_instance_parent_address_reg_timer_update(struct rpl_instance *instance, uint16_t seconds);

source/RPL/rpl_policy.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static int16_t rpl_policy_dao_initial_timeout_conf = 20; // Default is 2 seconds
4040
static uint16_t rpl_policy_dio_validity_period_hysteresis = 0x0180; //Fixed Point 1.5
4141
static uint8_t rpl_policy_multicast_config_min_advertisment_count = 0;
4242
static uint8_t rpl_policy_mrhof_parent_set_size_conf = 3; // default parent set size
43-
43+
static uint16_t rpl_policy_minimum_dao_target_refresh_conf = 0; // by default follow the configuration
4444
/* TODO - application API to control when to join new instances / DODAGs
4545
*
4646
* Eg, allow application to ignore local DODAGs, or specify known instance IDs,
@@ -115,6 +115,16 @@ void rpl_policy_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
115115
rpl_policy_dao_initial_timeout_conf = timeout_in_ms;
116116
}
117117

118+
void rpl_policy_set_minimum_dao_target_refresh(uint16_t seconds)
119+
{
120+
rpl_policy_minimum_dao_target_refresh_conf = seconds;
121+
}
122+
123+
uint16_t rpl_policy_minimum_dao_target_refresh(void)
124+
{
125+
return rpl_policy_minimum_dao_target_refresh_conf;
126+
}
127+
118128
uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop)
119129
{
120130
(void)mop;

0 commit comments

Comments
 (0)