From d8aa76501a26debd612108b9666daee2ce84b2f6 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Mon, 24 Aug 2020 16:27:09 +0200 Subject: [PATCH] net/gnrc/rpl: fix default route lifetime On receiving a DIO message, RPL sets the lifetime for the default route and the parent timeout event to the value. This leads to short amounts of time whem the node looses its default route, while it handles the parent timeout event to probe its parent. This commit fixes this by adding time the node needs for probing to the default route lifetime. --- sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c index 36892e7447..740ec94f13 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c @@ -66,6 +66,15 @@ static void _rpl_trickle_send_dio(void *args) ipv6_addr_to_str(addr_str,&dodag->dodag_id, sizeof(addr_str))); } +/* The lifetime of the default route should exceed the parent timeout interval + * by the time we allow the node to probe its parent */ +static uint16_t _dflt_route_lifetime_sec(gnrc_rpl_dodag_t *dodag) +{ + return (dodag->default_lifetime * dodag->lifetime_unit) + + (GNRC_RPL_PARENT_TIMEOUT * + (GNRC_RPL_PARENT_PROBE_INTERVAL / MS_PER_SEC)); +} + bool gnrc_rpl_instance_add(uint8_t instance_id, gnrc_rpl_instance_t **inst) { *inst = NULL; @@ -235,9 +244,8 @@ bool gnrc_rpl_parent_remove(gnrc_rpl_parent_t *parent) /* set the default route to the next parent for now */ if (parent->next) { - gnrc_ipv6_nib_ft_add(NULL, 0, - &parent->next->addr, dodag->iface, - dodag->default_lifetime * dodag->lifetime_unit * MS_PER_SEC); + gnrc_ipv6_nib_ft_add(NULL, 0, &parent->next->addr, dodag->iface, + _dflt_route_lifetime_sec(dodag)); } } LL_DELETE(dodag->parents, parent); @@ -278,7 +286,7 @@ void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent) if ((parent != NULL) && (parent->state != GNRC_RPL_PARENT_UNUSED)) { parent->state = GNRC_RPL_PARENT_ACTIVE; evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)&parent->timeout_event); - ((evtimer_event_t *)&(parent->timeout_event))->offset = dodag->default_lifetime * dodag->lifetime_unit * MS_PER_SEC; + ((evtimer_event_t *)&(parent->timeout_event))->offset = (dodag->default_lifetime - 1) * dodag->lifetime_unit * MS_PER_SEC; parent->timeout_event.msg.type = GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT; evtimer_add_msg(&gnrc_rpl_evtimer, &parent->timeout_event, gnrc_rpl_pid); #ifdef MODULE_GNRC_RPL_P2P @@ -287,7 +295,7 @@ void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent) if (parent == dodag->parents) { gnrc_ipv6_nib_ft_del(NULL, 0); gnrc_ipv6_nib_ft_add(NULL, 0, &parent->addr, dodag->iface, - dodag->default_lifetime * dodag->lifetime_unit); + _dflt_route_lifetime_sec(dodag)); } #ifdef MODULE_GNRC_RPL_P2P }