Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions sys/include/net/gnrc/rpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
#include "net/gnrc/rpl/dodag.h"
#include "net/gnrc/rpl/of_manager.h"
#include "net/fib.h"
#include "time_units.h"
#include "trickle.h"

#ifdef MODULE_NETSTATS_RPL
Expand Down Expand Up @@ -297,7 +298,7 @@
#define GNRC_RPL_COUNTER_MAX (255)
#define GNRC_RPL_COUNTER_LOWER_REGION (127)
#define GNRC_RPL_COUNTER_SEQ_WINDOW (16)
#define GNRC_RPL_COUNTER_INIT (GNRC_RPL_COUNTER_MAX - GNRC_RPL_COUNTER_SEQ_WINDOW + 1)

Check warning on line 301 in sys/include/net/gnrc/rpl.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

static inline uint8_t GNRC_RPL_COUNTER_INCREMENT(uint8_t counter)
{
Expand Down Expand Up @@ -516,7 +517,7 @@
#define GNRC_RPL_PRF_MASK (0x7)
/** @} */


Check warning on line 520 in sys/include/net/gnrc/rpl.h

View workflow job for this annotation

GitHub Actions / static-tests

too many consecutive empty lines
/**
* @brief Rank of the root node
*/
Expand Down Expand Up @@ -565,7 +566,7 @@
* RFC 6550, section 3.5.1, Rank Comparison (DAGRank())
* </a>
*/
#define DAGRANK(rank,mhri) (rank/mhri)

Check warning on line 569 in sys/include/net/gnrc/rpl.h

View workflow job for this annotation

GitHub Actions / static-tests

comma should be followed by whitespace

/**
* @name Global / Local instance id masks
Expand Down Expand Up @@ -627,6 +628,13 @@
#define CONFIG_GNRC_RPL_PARENT_TIMEOUT_DIS_RETRIES (3)
#endif

/**
* @brief Timeout for floating DODAGs in milliseconds.
*/
#ifndef CONFIG_GNRC_RPL_DODAG_FLOAT_TIMEOUT
# define CONFIG_GNRC_RPL_DODAG_FLOAT_TIMEOUT (15 * MS_PER_SEC * SEC_PER_MIN)
#endif

/**
* @brief Default network interface for GNRC RPL
*/
Expand Down
16 changes: 16 additions & 0 deletions sys/include/net/gnrc/rpl/dodag.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ void gnrc_rpl_instance_remove(gnrc_rpl_instance_t *inst);
*/
gnrc_rpl_instance_t *gnrc_rpl_instance_get(uint8_t instance_id);

/**
* @brief Setup self as root for the @p dodag.
*
* @param[in] dodag Pointer to the dodag.
*/
void gnrc_rpl_dodag_root_init(gnrc_rpl_dodag_t *dodag);

/**
* @brief Initialize a new RPL DODAG with the id @p dodag_id for the instance @p instance.
*
Expand Down Expand Up @@ -159,6 +166,15 @@ void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent);
*/
void gnrc_rpl_cleanup_start(gnrc_rpl_dodag_t *dodag);

/**
* @brief Poison all routes of @p dodag by setting an infinite rank, and schedule
* a cleanup for the @p dodag.
*
* @param[in] dodag Pointer to the DODAG
*
*/
void gnrc_rpl_poison_routes(gnrc_rpl_dodag_t *dodag);

/**
* @brief Start a local repair.
*
Expand Down
4 changes: 4 additions & 0 deletions sys/include/net/gnrc/rpl/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@
* @param[in] dodag RPL dodag object.
*/
void (*reset)(gnrc_rpl_dodag_t *dodag);
void (*parent_state_callback)(gnrc_rpl_parent_t *, int, int); /**< retrieves the state of a parent*/

Check warning on line 297 in sys/include/net/gnrc/rpl/structs.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

/**
* @brief Initialize the objective function.
Expand Down Expand Up @@ -330,6 +330,10 @@
uint8_t dio_opts; /**< options in the next DIO
(see @ref GNRC_RPL_REQ_DIO_OPTS "DIO Options") */
evtimer_msg_event_t dao_event; /**< DAO TX events (see @ref GNRC_RPL_MSG_TYPE_DODAG_DAO_TX) */
/**
* floating dodag timeout events (see @ref GNRC_RPL_MSG_TYPE_DODAG_FLOAT_TIMEOUT)
*/
evtimer_msg_event_t float_timeout_event;
trickle_t trickle; /**< trickle representation */
};

Expand Down Expand Up @@ -361,7 +365,7 @@
/**
* @brief internal unpacked struct type for DIS solicited option insertion
*/
typedef struct {

Check warning on line 368 in sys/include/net/gnrc/rpl/structs.h

View workflow job for this annotation

GitHub Actions / static-tests

keyword 'struct' not followed by a single space
uint8_t type; /**< Option Type: 0x07 */
uint8_t length; /**< Option Length: 19 bytes*/
uint8_t instance_id; /**< id of the instance */
Expand Down
41 changes: 16 additions & 25 deletions sys/net/gnrc/routing/rpl/gnrc_rpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,37 +141,14 @@ gnrc_rpl_instance_t *gnrc_rpl_root_init(uint8_t instance_id, const ipv6_addr_t *
instance_id = gnrc_rpl_gen_instance_id(local_inst_id);
}

gnrc_rpl_dodag_t *dodag = NULL;
gnrc_rpl_instance_t *inst = gnrc_rpl_root_instance_init(instance_id, dodag_id,
GNRC_RPL_DEFAULT_MOP);

if (!inst) {
return NULL;
}

dodag = &inst->dodag;

dodag->dtsn = 1;
dodag->prf = 0;
dodag->dio_interval_doubl = CONFIG_GNRC_RPL_DEFAULT_DIO_INTERVAL_DOUBLINGS;
dodag->dio_min = CONFIG_GNRC_RPL_DEFAULT_DIO_INTERVAL_MIN;
dodag->dio_redun = CONFIG_GNRC_RPL_DEFAULT_DIO_REDUNDANCY_CONSTANT;
dodag->default_lifetime = CONFIG_GNRC_RPL_DEFAULT_LIFETIME;
dodag->lifetime_unit = CONFIG_GNRC_RPL_LIFETIME_UNIT;
dodag->version = GNRC_RPL_COUNTER_INIT;
dodag->grounded = GNRC_RPL_GROUNDED;
dodag->node_status = GNRC_RPL_ROOT_NODE;
dodag->my_rank = GNRC_RPL_ROOT_RANK;
dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_DODAG_CONF;

if (!IS_ACTIVE(CONFIG_GNRC_RPL_WITHOUT_PIO)) {
dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_PREFIX_INFO;
}

trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG,
(1 << dodag->dio_min), dodag->dio_interval_doubl,
dodag->dio_redun);
gnrc_rpl_rpble_update(dodag);
gnrc_rpl_dodag_root_init(&inst->dodag);
gnrc_rpl_rpble_update(&inst->dodag);

return inst;
}
Expand Down Expand Up @@ -273,6 +250,15 @@ static void _parent_timeout(gnrc_rpl_parent_t *parent)
evtimer_add_msg(&gnrc_rpl_evtimer, &parent->timeout_event, gnrc_rpl_pid);
}

/* Handle timeout for floating DODAG by poisoning all routes. */
static void _dodag_float_timeout(gnrc_rpl_dodag_t *dodag)
{
if (dodag->grounded != GNRC_RPL_GROUNDED) {
gnrc_rpl_poison_routes(dodag);
}
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->float_timeout_event);
}

static void *_event_loop(void *args)
{
msg_t msg, reply;
Expand Down Expand Up @@ -323,6 +309,11 @@ static void *_event_loop(void *args)
gnrc_rpl_instance_remove(instance);
}
break;
case GNRC_RPL_MSG_TYPE_DODAG_FLOAT_TIMEOUT:
DEBUG("RPL: GNRC_RPL_MSG_TYPE_DODAG_FLOAT_TIMEOUT received\n");
instance = msg.content.ptr;
_dodag_float_timeout(&instance->dodag);
break;
case GNRC_RPL_MSG_TYPE_TRICKLE_MSG:
DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_MSG received\n");
trickle = msg.content.ptr;
Expand Down
73 changes: 68 additions & 5 deletions sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@

gnrc_rpl_send_DIO(inst, (ipv6_addr_t *) &ipv6_addr_all_rpl_nodes);
DEBUG("trickle callback: Instance (%d) | DODAG: (%s)\n", inst->id,
ipv6_addr_to_str(addr_str,&dodag->dodag_id, sizeof(addr_str)));

Check warning on line 68 in sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c

View workflow job for this annotation

GitHub Actions / static-tests

comma should be followed by whitespace
}

/* The lifetime of the default route should exceed the parent timeout interval
Expand All @@ -77,6 +77,18 @@
(GNRC_RPL_PARENT_PROBE_INTERVAL / MS_PER_SEC));
}

void gnrc_rpl_poison_routes(gnrc_rpl_dodag_t *dodag)
{
if (dodag->my_rank != GNRC_RPL_INFINITE_RANK) {
DEBUG("RPL: Poison all children routes in DODAG.\n");

/* Poison routes by advertising infinity rank */
dodag->my_rank = GNRC_RPL_INFINITE_RANK;
trickle_reset_timer(&dodag->trickle);
gnrc_rpl_cleanup_start(dodag);
}
}

bool gnrc_rpl_instance_add(uint8_t instance_id, gnrc_rpl_instance_t **inst)
{
*inst = NULL;
Expand Down Expand Up @@ -113,7 +125,7 @@

bool gnrc_rpl_instance_remove_by_id(uint8_t instance_id)
{
for(uint8_t i = 0; i < GNRC_RPL_INSTANCES_NUMOF; ++i) {

Check warning on line 128 in sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c

View workflow job for this annotation

GitHub Actions / static-tests

keyword 'for' not followed by a single space
if (gnrc_rpl_instances[i].id == instance_id) {
gnrc_rpl_instance_remove(&gnrc_rpl_instances[i]);
return true;
Expand All @@ -130,8 +142,9 @@
gnrc_rpl_dodag_remove_all_parents(dodag);
trickle_stop(&dodag->trickle);
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->dao_event);
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->float_timeout_event);
evtimer_del(&gnrc_rpl_evtimer, (evtimer_event_t *)&dodag->instance->cleanup_event);

memset(dodag, 0, sizeof(gnrc_rpl_dodag_t));
}

void gnrc_rpl_instance_remove(gnrc_rpl_instance_t *inst)
Expand All @@ -150,6 +163,30 @@
return NULL;
}

void gnrc_rpl_dodag_root_init(gnrc_rpl_dodag_t *dodag)
{
dodag->dtsn = 1;
dodag->prf = 0;
dodag->dio_interval_doubl = CONFIG_GNRC_RPL_DEFAULT_DIO_INTERVAL_DOUBLINGS;
dodag->dio_min = CONFIG_GNRC_RPL_DEFAULT_DIO_INTERVAL_MIN;
dodag->dio_redun = CONFIG_GNRC_RPL_DEFAULT_DIO_REDUNDANCY_CONSTANT;
dodag->default_lifetime = CONFIG_GNRC_RPL_DEFAULT_LIFETIME;
dodag->lifetime_unit = CONFIG_GNRC_RPL_LIFETIME_UNIT;
dodag->version = GNRC_RPL_COUNTER_INIT;
dodag->grounded = GNRC_RPL_GROUNDED;
dodag->node_status = GNRC_RPL_ROOT_NODE;
dodag->my_rank = GNRC_RPL_ROOT_RANK;
dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_DODAG_CONF;

if (!IS_ACTIVE(CONFIG_GNRC_RPL_WITHOUT_PIO)) {
dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_PREFIX_INFO;
}

trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG,
(1 << dodag->dio_min), dodag->dio_interval_doubl,
dodag->dio_redun);
}

bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, const ipv6_addr_t *dodag_id,
kernel_pid_t iface)
{
Expand All @@ -176,6 +213,8 @@
dodag->iface = iface;
dodag->dao_event.msg.content.ptr = instance;
dodag->dao_event.msg.type = GNRC_RPL_MSG_TYPE_DODAG_DAO_TX;
dodag->float_timeout_event.msg.content.ptr = instance;
dodag->float_timeout_event.msg.type = GNRC_RPL_MSG_TYPE_DODAG_FLOAT_TIMEOUT;

if ((netif != NULL) && !(netif->flags & GNRC_NETIF_FLAGS_IPV6_FORWARDING)) {
gnrc_rpl_leaf_operation(dodag);
Expand All @@ -191,6 +230,32 @@
return true;
}

bool _float_dodag(gnrc_rpl_dodag_t *dodag)
{
evtimer_event_t *float_event = (evtimer_event_t *)&dodag->float_timeout_event;

DEBUG("RPL: Set node as root for floating DODAG.\n");

evtimer_del(&gnrc_rpl_evtimer, float_event);

/* find address on interface that matches the prefix of the old dodag */
gnrc_netif_t *netif = gnrc_netif_get_by_pid(dodag->iface);
int idx = gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id);
if (idx < 0) {
DEBUG("RPL: could not find address to use as DODAGID.");
return false;
}
dodag->dodag_id = netif->ipv6.addrs[idx];
gnrc_rpl_dodag_root_init(dodag);
dodag->grounded &= !GNRC_RPL_GROUNDED;

/* floating dodag should timeout eventually if no new grounded dodag is found */
float_event->offset = CONFIG_GNRC_RPL_DODAG_FLOAT_TIMEOUT;
evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->float_timeout_event, gnrc_rpl_pid);

return true;
}

void gnrc_rpl_dodag_remove_all_parents(gnrc_rpl_dodag_t *dodag)
{
gnrc_rpl_parent_t *elt = NULL;
Expand Down Expand Up @@ -228,7 +293,7 @@
(*parent)->state = GNRC_RPL_PARENT_ACTIVE;
(*parent)->addr = *addr;
(*parent)->rank = GNRC_RPL_INFINITE_RANK;
evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)(&(*parent)->timeout_event));

Check warning on line 296 in sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
((evtimer_event_t *)(&(*parent)->timeout_event))->next = NULL;
(*parent)->timeout_event.msg.type = GNRC_RPL_MSG_TYPE_PARENT_TIMEOUT;
(*parent)->timeout_event.msg.content.ptr = (*parent);
Expand Down Expand Up @@ -264,7 +329,7 @@

void gnrc_rpl_cleanup_start(gnrc_rpl_dodag_t *dodag)
{
evtimer_del((evtimer_t *)(&gnrc_rpl_evtimer), (evtimer_event_t *)&dodag->instance->cleanup_event);

Check warning on line 332 in sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
((evtimer_event_t *)&(dodag->instance->cleanup_event))->offset = CONFIG_GNRC_RPL_CLEANUP_TIME;
dodag->instance->cleanup_event.msg.type = GNRC_RPL_MSG_TYPE_INSTANCE_CLEANUP;
evtimer_add_msg(&gnrc_rpl_evtimer, &dodag->instance->cleanup_event, gnrc_rpl_pid);
Expand All @@ -276,10 +341,8 @@

dodag->dtsn++;

if (dodag->my_rank != GNRC_RPL_INFINITE_RANK) {
dodag->my_rank = GNRC_RPL_INFINITE_RANK;
trickle_reset_timer(&dodag->trickle);
gnrc_rpl_cleanup_start(dodag);
if ((CONFIG_GNRC_RPL_DODAG_FLOAT_TIMEOUT <= 0) || !_float_dodag(dodag)) {
gnrc_rpl_poison_routes(dodag);
}

if (dodag->parents) {
Expand All @@ -294,7 +357,7 @@
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 - 1) * dodag->lifetime_unit * MS_PER_SEC;

Check warning on line 360 in sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
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
Expand Down
4 changes: 4 additions & 0 deletions sys/net/gnrc/routing/rpl/gnrc_rpl_internal/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ extern evtimer_msg_t gnrc_rpl_evtimer;
* @brief Message type for DAO transmissions.
*/
#define GNRC_RPL_MSG_TYPE_DODAG_DAO_TX (0x0906)
/**
* @brief Message type for floating DODAG timeouts.
*/
#define GNRC_RPL_MSG_TYPE_DODAG_FLOAT_TIMEOUT (0x0907)
/** @} */

/**
Expand Down