Skip to content

Commit d492575

Browse files
Mika TervonenJuha Heiskanen
authored andcommitted
Modified ARO registrations timeouts from the address lifetime
ARO registrations are changed to the same length as Link timeout Created periodic timer to update ARO registrations at NUD interval This prevents NUDS to be sent to parent and replaced with ARO messages In RPL created interface to allow flexible address registration time ARO registrations update link timeout for parents if cild links are about to die NUD is sent
1 parent b898f04 commit d492575

File tree

15 files changed

+154
-42
lines changed

15 files changed

+154
-42
lines changed

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry
9898
static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr);
9999
static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
100100

101+
static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16]);
102+
101103

102104
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
103105
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
@@ -161,7 +163,7 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
161163
//Trig Address Registartion only when Bootstrap is ready
162164
if (interface->nwk_bootstrap_state == ER_BOOTSRAP_DONE && addr->source != ADDR_SOURCE_DHCP) {
163165
tr_debug("Address registration %s", trace_ipv6(addr->address));
164-
rpl_control_register_address(interface, addr->address);
166+
ws_address_registration_update(interface, addr->address);
165167
}
166168
if (addr_ipv6_scope(addr->address, interface) > IPV6_SCOPE_LINK_LOCAL) {
167169
// at least ula address available inside mesh.
@@ -192,7 +194,7 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
192194
if (addr->source != ADDR_SOURCE_DHCP) {
193195
tr_debug("Address Re registration %s", trace_ipv6(addr->address));
194196
//Register
195-
rpl_control_register_address(interface, addr->address);
197+
ws_address_registration_update(interface, addr->address);
196198
}
197199
}
198200
}
@@ -1622,12 +1624,19 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
16221624

16231625
if (time_from_start > WS_NEIGHBOR_NUD_TIMEOUT) {
16241626

1625-
if (ipv6_neighbour_has_registered_by_eui64(&cur->ipv6_neighbour_cache, entry_ptr->mac64)) {
1626-
// This is our child with valid ARO registration Change link timeout to future we check at 2 minute intervals
1627-
entry_ptr->lifetime = entry_ptr->lifetime + 120;
1628-
if (entry_ptr->lifetime > entry_ptr->link_lifetime) {
1629-
entry_ptr->lifetime = entry_ptr->link_lifetime;
1630-
}
1627+
/* For parents ARO registration is sent in link timeout times
1628+
* For candidate parents NUD is needed
1629+
* For children NUD is sent only at very close to end
1630+
*/
1631+
if (ipv6_neighbour_has_registered_by_eui64(&cur->ipv6_neighbour_cache, entry_ptr->mac64) &&
1632+
(time_from_start < WS_NEIGHBOR_NUD_TIMEOUT * 1.8)) {
1633+
/* This is our child with valid ARO registration send NUD if we are close to delete
1634+
*
1635+
* if ARO was received link is considered active so this is only in case of very long ARO registration times
1636+
*
1637+
* 1.8 means with link timeout of 30 minutes that NUD is sent 6 minutes before timeout
1638+
*
1639+
*/
16311640
return false;
16321641
}
16331642

@@ -1993,10 +2002,33 @@ static void ws_set_fhss_hop(protocol_interface_info_entry_t *cur)
19932002
tr_debug("own hop: %u, own rank: %u, rank inc: %u", own_hop, own_rank, rank_inc);
19942003
}
19952004

1996-
static void ws_address_registration_update(protocol_interface_info_entry_t *interface)
2005+
static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16])
2006+
{
2007+
rpl_control_register_address(interface, addr);
2008+
// Timer is used only to track full registrations
2009+
2010+
if (addr != NULL && interface->ws_info->aro_registration_timer) {
2011+
// Single address update and timer is running
2012+
return;
2013+
}
2014+
2015+
if (interface->ws_info->aro_registration_timer == 0) {
2016+
// Timer expired and check if we have valid address to register
2017+
ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) {
2018+
if (!addr_is_ipv6_link_local(address->address)) {
2019+
// We have still valid addresses let the timer run for next period
2020+
tr_info("ARO registration timer start");
2021+
interface->ws_info->aro_registration_timer = WS_NEIGHBOR_NUD_TIMEOUT;
2022+
return;
2023+
}
2024+
}
2025+
}
2026+
}
2027+
2028+
static void ws_address_parent_update(protocol_interface_info_entry_t *interface)
19972029
{
1998-
rpl_control_register_address(interface, NULL);
19992030
tr_info("RPL parent update ... register ARO");
2031+
ws_address_registration_update(interface, NULL);
20002032
}
20012033

20022034
static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
@@ -2042,7 +2074,7 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
20422074
*/
20432075

20442076
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
2045-
ws_address_registration_update(cur);
2077+
ws_address_parent_update(cur);
20462078
}
20472079
cur->ws_info->rpl_state = event;
20482080
tr_info("RPL event %d", event);
@@ -2057,7 +2089,7 @@ static void ws_dhcp_client_global_adress_cb(int8_t interface, uint8_t dhcp_addr[
20572089
if (register_status) {
20582090
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface);
20592091
if (cur) {
2060-
rpl_control_register_address(cur, prefix);
2092+
ws_address_registration_update(cur, prefix);
20612093
}
20622094
} else {
20632095
//Delete dhcpv6 client
@@ -2283,6 +2315,7 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
22832315
rpl_control_process_routes(protocol_6lowpan_rpl_domain, false); // Wi-SUN assumes that no default route needed
22842316
rpl_control_request_parent_link_confirmation(true);
22852317
rpl_control_set_dio_multicast_min_config_advertisment_count(WS_MIN_DIO_MULTICAST_CONFIG_ADVERTISMENT_COUNT);
2318+
rpl_control_set_address_registration_timeout((WS_NEIGHBOR_LINK_TIMEOUT / 60) + 1);
22862319
rpl_control_set_dao_retry_count(WS_MAX_DAO_RETRIES);
22872320
rpl_control_set_initial_dao_ack_wait(WS_MAX_DAO_INITIAL_TIMEOUT);
22882321
rpl_control_set_mrhof_parent_set_size(WS_MAX_PARENT_SET_COUNT);
@@ -3083,6 +3116,16 @@ void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t s
30833116
ws_bootstrap_event_discovery_start(cur);
30843117
}
30853118
}
3119+
if (cur->ws_info->aro_registration_timer) {
3120+
if (cur->ws_info->aro_registration_timer > seconds) {
3121+
cur->ws_info->aro_registration_timer -= seconds;
3122+
} else {
3123+
// Update all addressess. This function will update the timer value if needed
3124+
cur->ws_info->aro_registration_timer = 0;
3125+
ws_address_registration_update(cur, NULL);
3126+
}
3127+
}
3128+
30863129
}
30873130

30883131
void ws_primary_parent_update(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neighbor)
@@ -3105,7 +3148,7 @@ void ws_secondary_parent_update(protocol_interface_info_entry_t *interface)
31053148
if (interface->ws_info) {
31063149
ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) {
31073150
if (!addr_is_ipv6_link_local(address->address)) {
3108-
ws_address_registration_update(interface);
3151+
ws_address_parent_update(interface);
31093152
}
31103153
}
31113154
}

source/6LoWPAN/ws/ws_common.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,14 @@ uint8_t ws_common_allow_child_registration(protocol_interface_info_entry_t *inte
418418

419419
//Validate Is EUI64 already allocated for any address
420420
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, eui64)) {
421+
/*
422+
* ARO registration from child can update the link timeout so we don't need to send extra NUD if ARO received
423+
*/
424+
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, false, false);
425+
426+
if (mac_neighbor) {
427+
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(interface), mac_neighbor, mac_neighbor->link_lifetime);
428+
}
421429
tr_info("Child registration from old child");
422430
return ARO_SUCCESS;
423431
}

source/6LoWPAN/ws/ws_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ typedef struct ws_info_s {
8888
parent_info_t parent_info[WS_PARENT_LIST_SIZE];
8989
parent_info_list_t parent_list_free;
9090
parent_info_list_t parent_list_reserved;
91+
uint16_t aro_registration_timer; /**< Aro registration timer */
9192
uint16_t rpl_version_timer; /**< RPL version update timeout */
9293
uint32_t pan_timeout_timer; /**< routers will fallback to previous state after this */
9394
uint32_t pan_config_sol_max_timeout;

source/Common_Protocols/icmpv6.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,7 @@ void ack_remove_neighbour_cb(struct buffer *buffer_ptr, uint8_t status)
13771377

13781378
static void icmpv6_aro_cb(buffer_t *buf, uint8_t status)
13791379
{
1380+
(void)status;
13801381
uint8_t ll_address[16];
13811382
if (buf->dst_sa.addr_type == ADDR_IPV6) {
13821383
/*Full IPv6 address*/
@@ -1387,8 +1388,8 @@ static void icmpv6_aro_cb(buffer_t *buf, uint8_t status)
13871388
memcpy(ll_address + 8, &buf->dst_sa.address[2], 8);
13881389
ll_address[8] ^= 2;
13891390
}
1390-
rpl_control_address_register_done(buf->interface, ll_address, status);
1391-
if (status != SOCKET_TX_DONE) {
1391+
if (rpl_control_address_register_done(buf->interface, ll_address, status)) {
1392+
// When RPL returns true neighbor should be blacklisted
13921393
ws_common_aro_failure(buf->interface, ll_address);
13931394
}
13941395
}

source/RPL/rpl_control.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_cou
181181
rpl_policy_set_dio_multicast_config_advertisment_min_count(min_count);
182182
}
183183

184+
void rpl_control_set_address_registration_timeout(uint16_t timeout_in_minutes)
185+
{
186+
rpl_policy_set_address_registration_timeout(timeout_in_minutes);
187+
}
188+
184189
void rpl_control_set_dao_retry_count(uint8_t count)
185190
{
186191
rpl_policy_set_dao_retry_count(count);
@@ -201,6 +206,9 @@ void rpl_control_set_mrhof_parent_set_size(uint16_t parent_set_size)
201206
/* Send address registration to either specified address, or to non-registered address */
202207
void rpl_control_register_address(protocol_interface_info_entry_t *interface, const uint8_t addr[16])
203208
{
209+
if (!interface->rpl_domain) {
210+
return;
211+
}
204212
if (!rpl_policy_parent_confirmation_requested()) {
205213
return;
206214
}
@@ -209,21 +217,23 @@ void rpl_control_register_address(protocol_interface_info_entry_t *interface, co
209217
}
210218
}
211219

212-
void rpl_control_address_register_done(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16], uint8_t status)
220+
bool rpl_control_address_register_done(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16], uint8_t status)
213221
{
222+
bool blacklist_neighbour = false;
214223
if (!interface->rpl_domain) {
215-
return;
224+
return false;
216225
}
217226
if (!rpl_policy_parent_confirmation_requested()) {
218-
return;
227+
return false;
219228
}
220229

221230
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
222231
rpl_neighbour_t *neighbour = rpl_lookup_neighbour_by_ll_address(instance, ll_addr, interface->id);
223232
if (neighbour) {
224-
rpl_instance_address_registration_done(interface, instance, neighbour, status);
233+
blacklist_neighbour = blacklist_neighbour || rpl_instance_address_registration_done(interface, instance, neighbour, status);
225234
}
226235
}
236+
return blacklist_neighbour;
227237
}
228238

229239
bool rpl_control_is_dodag_parent(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16])

source/RPL/rpl_control.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,13 @@ bool rpl_control_find_worst_neighbor(struct protocol_interface_info_entry *inter
173173
/* Parent link confirmation API extension */
174174
void rpl_control_request_parent_link_confirmation(bool requested);
175175
void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_count);
176+
void rpl_control_set_address_registration_timeout(uint16_t timeout_in_minutes);
176177
void rpl_control_set_dao_retry_count(uint8_t count);
177178
void rpl_control_set_minimum_dao_target_refresh(uint16_t seconds);
178179
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms);
179180
void rpl_control_set_mrhof_parent_set_size(uint16_t parent_set_size);
180181
void rpl_control_register_address(struct protocol_interface_info_entry *interface, const uint8_t addr[16]);
181-
void rpl_control_address_register_done(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16], uint8_t status);
182+
bool rpl_control_address_register_done(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16], uint8_t status);
182183

183184
/* Configure and return the routing lookup predicate for a specified RPL instance ID */
184185
ipv6_route_predicate_fn_t *rpl_control_get_route_predicate(rpl_domain_t *domain, uint8_t instance_id, const uint8_t src[16], const uint8_t dst[16]);
@@ -202,7 +203,7 @@ uint8_t rpl_policy_mrhof_parent_set_size_get(const rpl_domain_t *domain);
202203
#define rpl_control_remove_domain_from_interface(cur) ((void) 0)
203204
#define rpl_control_free_domain_instances_from_interface(cur) ((void) 0)
204205
#define rpl_control_register_address(interface, addr) ((void) 0)
205-
#define rpl_control_address_register_done(interface, ll_addr, status) ((void) 0)
206+
#define rpl_control_address_register_done(interface, ll_addr, status) (false)
206207
#define rpl_policy_mrhof_parent_set_size_get(domain) (0)
207208
#define rpl_control_set_mrhof_parent_set_size(parent_set_size)
208209

source/RPL/rpl_downward.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,8 +1783,11 @@ static bool rpl_instance_push_address_registration(protocol_interface_info_entry
17831783

17841784
aro.status = ARO_SUCCESS;
17851785
aro.present = true;
1786-
aro.lifetime = (addr->valid_lifetime / 60) + 1;
17871786
memcpy(aro.eui64, interface->mac, 8);
1787+
aro.lifetime = rpl_policy_address_registration_timeout();
1788+
if (!aro.lifetime) {
1789+
aro.lifetime = (addr->valid_lifetime / 60) + 1;
1790+
}
17881791

17891792
buffer_t *buf = icmpv6_build_ns(interface, neighbour->ll_address, addr->address, true, false, &aro);
17901793
if (!buf) {
@@ -1819,6 +1822,13 @@ static void rpl_instance_address_registration_cancel(rpl_instance_t *instance)
18191822
instance->dao_retry_timer = 0;
18201823
}
18211824

1825+
static void rpl_instance_address_registration_retry(rpl_dao_target_t *dao_target)
1826+
{
1827+
dao_target->active_confirmation_state = true; // Active timer is set true so the response_wait_time runs out
1828+
dao_target->trig_confirmation_state = true;
1829+
dao_target->response_wait_time = 20; // Wait 20 seconds before retry
1830+
}
1831+
18221832
void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint16_t seconds)
18231833
{
18241834
if (!instance->pending_neighbour_confirmation) {
@@ -1873,41 +1883,48 @@ void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint
18731883
return;
18741884
}
18751885

1876-
18771886
if (rpl_instance_push_address_registration(interface, neighbour, address)) {
18781887
instance->wait_response = neighbour;
18791888
dao_target->response_wait_time = 5;
18801889
}
18811890

18821891
}
18831892

1884-
void rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status)
1893+
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status)
18851894
{
1886-
18871895
if (!instance->pending_neighbour_confirmation) {
1888-
return;
1896+
return false;
18891897
}
18901898

18911899
rpl_dao_target_t *dao_target = rpl_instance_get_active_target_confirmation(instance);
18921900
if (!dao_target || instance->wait_response != neighbour) {
1893-
return;
1901+
return false;
18941902
}
18951903

18961904
tr_debug("Address %s register to %s", trace_ipv6(dao_target->prefix), trace_ipv6(neighbour->ll_address));
18971905

1898-
if (status == SOCKET_TX_DONE) {
1899-
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
1900-
if_address_entry_t *address = rpl_interface_addr_get(interface, dao_target->prefix);
1901-
if (address && address->source != ADDR_SOURCE_DHCP) {
1902-
address->state_timer = (address->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
1906+
if (status != SOCKET_TX_DONE) {
1907+
if (neighbour->addr_reg_failures > 0) {
1908+
// Neighbor should be blacklisted after this.
1909+
tr_error("Address registration failed delete neighbor");
1910+
rpl_instance_address_registration_cancel(instance);
1911+
rpl_delete_neighbour(instance, neighbour);
1912+
return true;
19031913
}
1904-
neighbour->confirmed = true;
1905-
dao_target->response_wait_time = 6;
1906-
} else {
1907-
tr_error("Address registration failed");
1908-
rpl_delete_neighbour(instance, neighbour);
1909-
rpl_instance_address_registration_cancel(instance);
1914+
tr_warn("Address registration ACK fail retry selection");
1915+
neighbour->addr_reg_failures++;
1916+
rpl_instance_address_registration_retry(dao_target);
1917+
return false;
1918+
}
1919+
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
1920+
if_address_entry_t *address = rpl_interface_addr_get(interface, dao_target->prefix);
1921+
if (address && address->source != ADDR_SOURCE_DHCP) {
1922+
address->state_timer = (address->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
19101923
}
1924+
neighbour->addr_reg_failures = 0;
1925+
neighbour->confirmed = true;
1926+
dao_target->response_wait_time = 6;
1927+
return false;
19111928
}
19121929

19131930
#endif /* HAVE_RPL */

source/RPL/rpl_downward.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void rpl_instance_dao_trigger(struct rpl_instance *instance, uint16_t delay);
4343
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);
4444
void rpl_instance_parent_address_reg_timer_update(struct rpl_instance *instance, uint16_t seconds);
4545
void rpl_instance_send_address_registration(rpl_instance_t *instance, const uint8_t addr[16]);
46-
void rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status);
46+
bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, rpl_neighbour_t *neighbour, uint8_t status);
4747
struct rpl_dao_target *rpl_instance_get_active_target_confirmation(struct rpl_instance *instance);
4848

4949
#ifdef HAVE_RPL_DAO_HANDLING

source/RPL/rpl_policy.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ static uint16_t rpl_policy_dio_validity_period_hysteresis = 0x0180; //Fixed Poin
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
4343
static uint16_t rpl_policy_minimum_dao_target_refresh_conf = 0; // by default follow the configuration
44+
static uint16_t rpl_policy_address_registration_timeout_value = 0; // Address registration timeouts in minutes 0 use address lifetime
45+
4446
/* TODO - application API to control when to join new instances / DODAGs
4547
*
4648
* Eg, allow application to ignore local DODAGs, or specify known instance IDs,
@@ -391,6 +393,16 @@ void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_coun
391393
rpl_policy_multicast_config_min_advertisment_count = min_count;
392394
}
393395

396+
uint16_t rpl_policy_address_registration_timeout()
397+
{
398+
return rpl_policy_address_registration_timeout_value;
399+
}
400+
401+
void rpl_policy_set_address_registration_timeout(uint16_t timeout_in_minutes)
402+
{
403+
rpl_policy_address_registration_timeout_value = timeout_in_minutes;
404+
}
405+
394406

395407
#ifdef RPL_STRUCTURES_H_
396408
#error "rpl_structures.h should not be included by rpl_policy.c"

source/RPL/rpl_policy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,7 @@ bool rpl_policy_parent_confirmation_requested(void);
7171
void rpl_policy_set_parent_confirmation_request(bool confirmation_requested);
7272
uint8_t rpl_policy_dio_multicast_config_advertisment_min_count(void);
7373
void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_count);
74+
uint16_t rpl_policy_address_registration_timeout();
75+
void rpl_policy_set_address_registration_timeout(uint16_t timeout_in_minutes);
7476

7577
#endif /* RPL_POLICY_H_ */

source/RPL/rpl_structures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct rpl_neighbour {
5252
unsigned dodag_pref: 4; // Preference indication for DODAG parents (0=best)
5353
uint8_t dao_path_control; // Path control bit assignments for DAO parent
5454
uint8_t old_dao_path_control;
55+
uint8_t addr_reg_failures; // Address registration failure count (missing ACK)
5556
int8_t interface_id;
5657
uint8_t g_mop_prf;
5758
uint8_t dtsn;

0 commit comments

Comments
 (0)