From c5b0c051e5c295595f87c31b0f6696d504446cb9 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Tue, 1 Jul 2025 14:51:16 +0200 Subject: [PATCH 1/7] gnrc/rpl/control_messages: extract `_recv_DIO_for_existing_dodag` --- .../routing/rpl/gnrc_rpl_control_messages.c | 194 +++++++++--------- 1 file changed, 102 insertions(+), 92 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index 8dff23925d..a2c9f8de86 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -737,6 +737,107 @@ void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src } } +/** + * @brief Handles a received DIO message for an existing DODAG. + * + * @param[in] inst The @p RPL instance of the DODAG. + * @param[in] dio The received @p DIO packet. + * @param[in] src The address of the sender. + * @param[in] len The length of the DIO packet. + */ +static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, + ipv6_addr_t *src, uint16_t len) +{ + gnrc_rpl_dodag_t *dodag = &inst->dodag; + + /* ignore dodags with other dodag_id's for now */ + /* TODO: choose DODAG with better rank */ + if (memcmp(&dodag->dodag_id, &dio->dodag_id, sizeof(ipv6_addr_t)) != 0) { + DEBUG("RPL: DIO received from another DODAG, but same instance - ignore\n"); + return; + } + + if (inst->mop != ((dio->g_mop_prf >> GNRC_RPL_MOP_SHIFT) & GNRC_RPL_SHIFTED_MOP_MASK)) { + DEBUG("RPL: invalid MOP for this instance.\n"); + return; + } + +#ifdef MODULE_GNRC_RPL_P2P + gnrc_rpl_p2p_ext_t *p2p_ext = gnrc_rpl_p2p_ext_get(dodag); + if ((dodag->instance->mop == GNRC_RPL_P2P_MOP) && (p2p_ext->lifetime_sec <= 0)) { + return; + } +#endif + + if (GNRC_RPL_COUNTER_GREATER_THAN(dio->version_number, dodag->version)) { + if (dodag->node_status == GNRC_RPL_ROOT_NODE) { + dodag->version = GNRC_RPL_COUNTER_INCREMENT(dio->version_number); + trickle_reset_timer(&dodag->trickle); + } + else { + dodag->version = dio->version_number; + gnrc_rpl_local_repair(dodag); + } + } + else if (GNRC_RPL_COUNTER_GREATER_THAN(dodag->version, dio->version_number)) { + trickle_reset_timer(&dodag->trickle); + return; + } + + if (dodag->node_status == GNRC_RPL_ROOT_NODE) { + if (byteorder_ntohs(dio->rank) != GNRC_RPL_INFINITE_RANK) { + trickle_increment_counter(&dodag->trickle); + } + else { + trickle_reset_timer(&dodag->trickle); + } + return; + } + + gnrc_rpl_parent_t *parent = NULL; + + if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { + DEBUG("RPL: Could not allocate new parent.\n"); + return; + } + else if (parent != NULL) { + trickle_increment_counter(&dodag->trickle); + } + + /* gnrc_rpl_parent_add_by_addr should have set this already */ + assert(parent != NULL); + + parent->rank = byteorder_ntohs(dio->rank); + + gnrc_rpl_parent_update(dodag, parent); + + /* sender of incoming DIO is not a parent of mine (anymore) and has an INFINITE rank + and I have a rank != INFINITE_RANK */ + if (parent->state == GNRC_RPL_PARENT_UNUSED) { + if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) + && (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) { + trickle_reset_timer(&dodag->trickle); + return; + } + } + /* incoming DIO is from pref. parent */ + else if (parent == dodag->parents) { + if (parent->dtsn != dio->dtsn) { + gnrc_rpl_delay_dao(dodag); + } + parent->dtsn = dio->dtsn; + dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; + dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; + uint32_t included_opts = 0; + if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, + src, &included_opts)) { + DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); + gnrc_rpl_instance_remove(inst); + return; + } + } +} + void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, uint16_t len) { @@ -835,103 +936,12 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src dodag->dio_redun); gnrc_rpl_parent_update(dodag, parent); - return; } else if (inst == NULL) { DEBUG("RPL: Could not allocate a new instance.\n"); - return; } else { - /* instance exists already */ - /* ignore dodags with other dodag_id's for now */ - /* TODO: choose DODAG with better rank */ - - dodag = &inst->dodag; - - if (memcmp(&dodag->dodag_id, &dio->dodag_id, sizeof(ipv6_addr_t)) != 0) { - DEBUG("RPL: DIO received from another DODAG, but same instance - ignore\n"); - return; - } - } - - if (inst->mop != ((dio->g_mop_prf >> GNRC_RPL_MOP_SHIFT) & GNRC_RPL_SHIFTED_MOP_MASK)) { - DEBUG("RPL: invalid MOP for this instance.\n"); - return; - } - -#ifdef MODULE_GNRC_RPL_P2P - gnrc_rpl_p2p_ext_t *p2p_ext = gnrc_rpl_p2p_ext_get(dodag); - if ((dodag->instance->mop == GNRC_RPL_P2P_MOP) && (p2p_ext->lifetime_sec <= 0)) { - return; - } -#endif - - if (GNRC_RPL_COUNTER_GREATER_THAN(dio->version_number, dodag->version)) { - if (dodag->node_status == GNRC_RPL_ROOT_NODE) { - dodag->version = GNRC_RPL_COUNTER_INCREMENT(dio->version_number); - trickle_reset_timer(&dodag->trickle); - } - else { - dodag->version = dio->version_number; - gnrc_rpl_local_repair(dodag); - } - } - else if (GNRC_RPL_COUNTER_GREATER_THAN(dodag->version, dio->version_number)) { - trickle_reset_timer(&dodag->trickle); - return; - } - - if (dodag->node_status == GNRC_RPL_ROOT_NODE) { - if (byteorder_ntohs(dio->rank) != GNRC_RPL_INFINITE_RANK) { - trickle_increment_counter(&dodag->trickle); - } - else { - trickle_reset_timer(&dodag->trickle); - } - return; - } - - gnrc_rpl_parent_t *parent = NULL; - - if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { - DEBUG("RPL: Could not allocate new parent.\n"); - return; - } - else if (parent != NULL) { - trickle_increment_counter(&dodag->trickle); - } - - /* gnrc_rpl_parent_add_by_addr should have set this already */ - assert(parent != NULL); - - parent->rank = byteorder_ntohs(dio->rank); - - gnrc_rpl_parent_update(dodag, parent); - - /* sender of incoming DIO is not a parent of mine (anymore) and has an INFINITE rank - and I have a rank != INFINITE_RANK */ - if (parent->state == GNRC_RPL_PARENT_UNUSED) { - if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) - && (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) { - trickle_reset_timer(&dodag->trickle); - return; - } - } - /* incoming DIO is from pref. parent */ - else if (parent == dodag->parents) { - if (parent->dtsn != dio->dtsn) { - gnrc_rpl_delay_dao(dodag); - } - parent->dtsn = dio->dtsn; - dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; - dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; - uint32_t included_opts = 0; - if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, - src, &included_opts)) { - DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); - gnrc_rpl_instance_remove(inst); - return; - } + _recv_DIO_for_existing_dodag(inst, dio, src, len); } } From 0879645c2ec403811531390db6dedf7f2a2ff413 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Tue, 1 Jul 2025 14:53:08 +0200 Subject: [PATCH 2/7] gnrc/rpl/control_messages: extract `_recv_DIO_for_new_dodag` --- .../routing/rpl/gnrc_rpl_control_messages.c | 171 ++++++++++-------- 1 file changed, 92 insertions(+), 79 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index a2c9f8de86..a8a8ccebdc 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -737,6 +737,97 @@ void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src } } +/** + * @brief Handles a received DIO message for a new DODAG. + * + * @param[in] inst The @p RPL instance of the DODAG. + * @param[in] dio The received @p DIO packet. + * @param[in] iface The interface that the DIO was received on. + * @param[in] src The address of the sender. + * @param[in] len The length of the whole DIO packet. + */ +void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, kernel_pid_t iface, + ipv6_addr_t *src, uint16_t len) +{ + gnrc_netif_t *netif; + + if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) { + DEBUG("RPL: ignore INFINITE_RANK DIO when we are not yet part of this DODAG\n"); + gnrc_rpl_instance_remove(inst); + return; + } + + inst->mop = (dio->g_mop_prf >> GNRC_RPL_MOP_SHIFT) & GNRC_RPL_SHIFTED_MOP_MASK; + inst->of = gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); + + if (iface == KERNEL_PID_UNDEF) { + netif = _find_interface_with_rpl_mcast(); + } + else { + netif = gnrc_netif_get_by_pid(iface); + } + assert(netif != NULL); + + gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid); + + gnrc_rpl_dodag_t *dodag = &inst->dodag; + + DEBUG("RPL: Joined DODAG (%s).\n", + ipv6_addr_to_str(addr_str, &dio->dodag_id, sizeof(addr_str))); + + gnrc_rpl_parent_t *parent = NULL; + + if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { + DEBUG("RPL: Could not allocate new parent.\n"); + gnrc_rpl_instance_remove(inst); + return; + } + + dodag->version = dio->version_number; + dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; + dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; + + parent->rank = byteorder_ntohs(dio->rank); + + uint32_t included_opts = 0; + if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, + src, &included_opts)) { + DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); + gnrc_rpl_instance_remove(inst); + return; + } + + if (!(included_opts & (((uint32_t)1) << GNRC_RPL_OPT_DODAG_CONF))) { + if (!IS_ACTIVE(CONFIG_GNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN)) { + DEBUG("RPL: DIO without DODAG_CONF option - remove DODAG and request new DIO\n"); + gnrc_rpl_instance_remove(inst); + gnrc_rpl_send_DIS(NULL, src, NULL, 0); + return; + } + else { + DEBUG("RPL: DIO without DODAG_CONF option - use default trickle parameters\n"); + gnrc_rpl_send_DIS(NULL, src, NULL, 0); + } + } + + /* if there was no address created manually or by a PIO on the interface, + * leave this DODAG */ + if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) { + DEBUG("RPL: no IPv6 address configured on interface %i to match the " + "given dodag id: %s\n", netif->pid, + ipv6_addr_to_str(addr_str, &(dodag->dodag_id), sizeof(addr_str))); + gnrc_rpl_instance_remove(inst); + return; + } + + gnrc_rpl_delay_dao(dodag); + 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_parent_update(dodag, parent); +} + /** * @brief Handles a received DIO message for an existing DODAG. * @@ -843,7 +934,6 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src { (void)dst; gnrc_rpl_instance_t *inst = NULL; - gnrc_rpl_dodag_t *dodag = NULL; #ifdef MODULE_NETSTATS_RPL gnrc_rpl_netstats_rx_DIO(&gnrc_rpl_netstats, len, (dst && !ipv6_addr_is_multicast(dst))); @@ -858,84 +948,7 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src len -= (sizeof(gnrc_rpl_dio_t) + sizeof(icmpv6_hdr_t)); if (gnrc_rpl_instance_add(dio->instance_id, &inst)) { - /* new instance and DODAG */ - gnrc_netif_t *netif; - - if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) { - DEBUG("RPL: ignore INFINITE_RANK DIO when we are not yet part of this DODAG\n"); - gnrc_rpl_instance_remove(inst); - return; - } - - inst->mop = (dio->g_mop_prf >> GNRC_RPL_MOP_SHIFT) & GNRC_RPL_SHIFTED_MOP_MASK; - inst->of = gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); - - if (iface == KERNEL_PID_UNDEF) { - netif = _find_interface_with_rpl_mcast(); - } - else { - netif = gnrc_netif_get_by_pid(iface); - } - assert(netif != NULL); - - gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid); - - dodag = &inst->dodag; - - DEBUG("RPL: Joined DODAG (%s).\n", - ipv6_addr_to_str(addr_str, &dio->dodag_id, sizeof(addr_str))); - - gnrc_rpl_parent_t *parent = NULL; - - if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { - DEBUG("RPL: Could not allocate new parent.\n"); - gnrc_rpl_instance_remove(inst); - return; - } - - dodag->version = dio->version_number; - dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; - dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; - - parent->rank = byteorder_ntohs(dio->rank); - - uint32_t included_opts = 0; - if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, - src, &included_opts)) { - DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); - gnrc_rpl_instance_remove(inst); - return; - } - - if (!(included_opts & (((uint32_t)1) << GNRC_RPL_OPT_DODAG_CONF))) { - if (!IS_ACTIVE(CONFIG_GNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN)) { - DEBUG("RPL: DIO without DODAG_CONF option - remove DODAG and request new DIO\n"); - gnrc_rpl_instance_remove(inst); - gnrc_rpl_send_DIS(NULL, src, NULL, 0); - return; - } - else { - DEBUG("RPL: DIO without DODAG_CONF option - use default trickle parameters\n"); - gnrc_rpl_send_DIS(NULL, src, NULL, 0); - } - } - - /* if there was no address created manually or by a PIO on the interface, - * leave this DODAG */ - if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) { - DEBUG("RPL: no IPv6 address configured on interface %i to match the " - "given dodag id: %s\n", netif->pid, - ipv6_addr_to_str(addr_str, &(dodag->dodag_id), sizeof(addr_str))); - gnrc_rpl_instance_remove(inst); - return; - } - - gnrc_rpl_delay_dao(dodag); - 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_parent_update(dodag, parent); + _recv_DIO_for_new_dodag(inst, dio, iface, src, len); } else if (inst == NULL) { DEBUG("RPL: Could not allocate a new instance.\n"); From b80176333ad3cdf04a14e6413e69696004445969 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Mon, 30 Jun 2025 17:09:24 +0200 Subject: [PATCH 3/7] gnrc/rpl/control_messages: rearrange minor parts --- .../routing/rpl/gnrc_rpl_control_messages.c | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index a8a8ccebdc..b58102408a 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -750,6 +750,8 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker ipv6_addr_t *src, uint16_t len) { gnrc_netif_t *netif; + gnrc_rpl_dodag_t *dodag; + gnrc_rpl_parent_t *parent = NULL; if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) { DEBUG("RPL: ignore INFINITE_RANK DIO when we are not yet part of this DODAG\n"); @@ -757,9 +759,6 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker return; } - inst->mop = (dio->g_mop_prf >> GNRC_RPL_MOP_SHIFT) & GNRC_RPL_SHIFTED_MOP_MASK; - inst->of = gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); - if (iface == KERNEL_PID_UNDEF) { netif = _find_interface_with_rpl_mcast(); } @@ -768,14 +767,15 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker } assert(netif != NULL); + inst->mop = (dio->g_mop_prf >> GNRC_RPL_MOP_SHIFT) & GNRC_RPL_SHIFTED_MOP_MASK; + inst->of = gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); + gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid); - gnrc_rpl_dodag_t *dodag = &inst->dodag; + dodag = &inst->dodag; DEBUG("RPL: Joined DODAG (%s).\n", - ipv6_addr_to_str(addr_str, &dio->dodag_id, sizeof(addr_str))); - - gnrc_rpl_parent_t *parent = NULL; + ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str))); if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { DEBUG("RPL: Could not allocate new parent.\n"); @@ -783,11 +783,14 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker return; } - dodag->version = dio->version_number; - dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; - dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; + gnrc_rpl_delay_dao(dodag); + uint32_t interval_min = 1 << dodag->dio_min; + uint8_t interval_max = dodag->dio_interval_doubl; + trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG, + interval_min, interval_max, dodag->dio_redun); parent->rank = byteorder_ntohs(dio->rank); + gnrc_rpl_parent_update(dodag, parent); uint32_t included_opts = 0; if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, @@ -812,20 +815,17 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker /* if there was no address created manually or by a PIO on the interface, * leave this DODAG */ - if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) { + if (gnrc_netif_ipv6_addr_match(netif, &dio->dodag_id) < 0) { DEBUG("RPL: no IPv6 address configured on interface %i to match the " "given dodag id: %s\n", netif->pid, - ipv6_addr_to_str(addr_str, &(dodag->dodag_id), sizeof(addr_str))); + ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str))); gnrc_rpl_instance_remove(inst); return; } - gnrc_rpl_delay_dao(dodag); - 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_parent_update(dodag, parent); + dodag->version = dio->version_number; + dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; + dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; } /** @@ -891,13 +891,12 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio DEBUG("RPL: Could not allocate new parent.\n"); return; } - else if (parent != NULL) { - trickle_increment_counter(&dodag->trickle); - } /* gnrc_rpl_parent_add_by_addr should have set this already */ assert(parent != NULL); + trickle_increment_counter(&dodag->trickle); + parent->rank = byteorder_ntohs(dio->rank); gnrc_rpl_parent_update(dodag, parent); @@ -908,11 +907,12 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) && (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) { trickle_reset_timer(&dodag->trickle); - return; } + return; } + /* incoming DIO is from pref. parent */ - else if (parent == dodag->parents) { + if (parent == dodag->parents) { if (parent->dtsn != dio->dtsn) { gnrc_rpl_delay_dao(dodag); } From ca2f13fa20fd01e6cdcc953cfe919c448167fef4 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Mon, 30 Jun 2025 17:14:24 +0200 Subject: [PATCH 4/7] gnrc/rpl/control_messages: extract DIO opts parsing --- .../routing/rpl/gnrc_rpl_control_messages.c | 84 ++++++++++++------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index b58102408a..be0a93fc63 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -25,6 +25,7 @@ #include "xtimer.h" #endif +#include "bit.h" #include "net/af.h" #include "net/icmpv6.h" #include "net/ipv6/hdr.h" @@ -533,19 +534,19 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt switch (opt->type) { case (GNRC_RPL_OPT_PAD1): DEBUG("RPL: PAD1 option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_PAD1; + bit_set32(included_opts, GNRC_RPL_OPT_PAD1); len_parsed += 1; opt = (gnrc_rpl_opt_t *)(((uint8_t *)opt) + 1); continue; case (GNRC_RPL_OPT_PADN): DEBUG("RPL: PADN option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_PADN; + bit_set32(included_opts, GNRC_RPL_OPT_PADN); break; case (GNRC_RPL_OPT_DODAG_CONF): DEBUG("RPL: DODAG CONF DIO option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_DODAG_CONF; + bit_set32(included_opts, GNRC_RPL_OPT_DODAG_CONF); dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_DODAG_CONF; gnrc_rpl_opt_dodag_conf_t *dc = (gnrc_rpl_opt_dodag_conf_t *)opt; gnrc_rpl_of_t *of = gnrc_rpl_get_of_for_ocp(byteorder_ntohs(dc->ocp)); @@ -570,7 +571,7 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt case (GNRC_RPL_OPT_PREFIX_INFO): DEBUG("RPL: Prefix Information DIO option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_PREFIX_INFO; + bit_set32(included_opts, GNRC_RPL_OPT_PREFIX_INFO); if (!IS_ACTIVE(CONFIG_GNRC_RPL_WITHOUT_PIO)) { dodag->dio_opts |= GNRC_RPL_REQ_DIO_OPT_PREFIX_INFO; @@ -597,7 +598,7 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt break; case (GNRC_RPL_OPT_SOLICITED_INFO): DEBUG("RPL: RPL SOLICITED INFO option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_SOLICITED_INFO; + bit_set32(included_opts, GNRC_RPL_OPT_SOLICITED_INFO); gnrc_rpl_opt_dis_solicited_t *sol = (gnrc_rpl_opt_dis_solicited_t *)opt; /* check expected length */ @@ -630,7 +631,7 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt break; case (GNRC_RPL_OPT_TARGET): DEBUG("RPL: RPL TARGET DAO option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_TARGET; + bit_set32(included_opts, GNRC_RPL_OPT_TARGET); gnrc_rpl_opt_target_t *target = (gnrc_rpl_opt_target_t *)opt; if (first_target == NULL) { @@ -649,7 +650,8 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt case (GNRC_RPL_OPT_TRANSIT): DEBUG("RPL: RPL TRANSIT INFO DAO option parsed\n"); - *included_opts |= ((uint32_t)1) << GNRC_RPL_OPT_TRANSIT; + bit_set32(included_opts, GNRC_RPL_OPT_TRANSIT); + gnrc_rpl_opt_transit_t *transit = (gnrc_rpl_opt_transit_t *)opt; if (first_target == NULL) { DEBUG("RPL: Encountered a RPL TRANSIT DAO option without " @@ -737,6 +739,49 @@ void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src } } +/** + * @brief Handles the options from a received DIO packet. + * + * @param[in] inst The @p RPL instance that the DIO belongs to. + * @param[in] dio The @p DIO packet. + * @param[in] src The address of the sender. + * @param[in] len The length of the whole DIO packet. + * @param[in] is_new Whether the DIO belongs to an existing or newly created DODAG. + * + * @retval True on success. + * @retval False if parsing of the options failed. + * @retval False if the DODAG is new and the GNRC_RPL_OPT_DODAG_CONF option + * is required but missing. + */ +static bool _handle_DIO_opts(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv6_addr_t *src, + uint16_t len, bool is_new) +{ + gnrc_rpl_opt_t *opts = (gnrc_rpl_opt_t *)(dio + 1); + uint32_t included_opts = 0; + + /* subtract length of ICMPv6 header and DIO base object fields to get length of DIO options */ + size_t opt_len = len - sizeof(gnrc_rpl_dio_t) - sizeof(icmpv6_hdr_t); + + if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, opts, opt_len, src, &included_opts)) { + DEBUG("RPL: Error encountered during DIO option parsing\n"); + return false; + } + + if (is_new && !bit_check32(&included_opts, GNRC_RPL_OPT_DODAG_CONF)) { + if (!IS_ACTIVE(CONFIG_GNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN)) { + DEBUG("RPL: DIO without DODAG_CONF option - request new DIO\n"); + gnrc_rpl_send_DIS(NULL, src, NULL, 0); + return false; + } + else { + DEBUG("RPL: DIO without DODAG_CONF option - use default trickle parameters\n"); + gnrc_rpl_send_DIS(NULL, src, NULL, 0); + } + } + + return true; +} + /** * @brief Handles a received DIO message for a new DODAG. * @@ -792,27 +837,11 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker parent->rank = byteorder_ntohs(dio->rank); gnrc_rpl_parent_update(dodag, parent); - uint32_t included_opts = 0; - if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, - src, &included_opts)) { - DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); + if (!_handle_DIO_opts(inst, dio, src, len, true)) { gnrc_rpl_instance_remove(inst); return; } - if (!(included_opts & (((uint32_t)1) << GNRC_RPL_OPT_DODAG_CONF))) { - if (!IS_ACTIVE(CONFIG_GNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN)) { - DEBUG("RPL: DIO without DODAG_CONF option - remove DODAG and request new DIO\n"); - gnrc_rpl_instance_remove(inst); - gnrc_rpl_send_DIS(NULL, src, NULL, 0); - return; - } - else { - DEBUG("RPL: DIO without DODAG_CONF option - use default trickle parameters\n"); - gnrc_rpl_send_DIS(NULL, src, NULL, 0); - } - } - /* if there was no address created manually or by a PIO on the interface, * leave this DODAG */ if (gnrc_netif_ipv6_addr_match(netif, &dio->dodag_id) < 0) { @@ -919,9 +948,8 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio parent->dtsn = dio->dtsn; dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; - uint32_t included_opts = 0; - if (!_parse_options(GNRC_RPL_ICMPV6_CODE_DIO, inst, (gnrc_rpl_opt_t *)(dio + 1), len, - src, &included_opts)) { + + if (!_handle_DIO_opts(inst, dio, src, len, false)) { DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); gnrc_rpl_instance_remove(inst); return; @@ -945,8 +973,6 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src } } - len -= (sizeof(gnrc_rpl_dio_t) + sizeof(icmpv6_hdr_t)); - if (gnrc_rpl_instance_add(dio->instance_id, &inst)) { _recv_DIO_for_new_dodag(inst, dio, iface, src, len); } From f618e59e63040b7a29b86b048bbc23042246ffe6 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Tue, 1 Jul 2025 09:05:34 +0200 Subject: [PATCH 5/7] gnrc/rpl/control_messages: extract `update_dodag_from_DIO` Extract commit logic from `_recv_DIO_for_{existing,new}_dodag` into new function `_update_dodag_from_DIO`. The function updates the dodag and parent based on the DIO data. --- .../routing/rpl/gnrc_rpl_control_messages.c | 159 +++++++++--------- 1 file changed, 83 insertions(+), 76 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index be0a93fc63..d4c4b6346d 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -782,6 +782,85 @@ static bool _handle_DIO_opts(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv return true; } +/** + * @brief Updates a DODAG with the info from a received DIO packet. + * + * @param[in] inst The @p RPL instance of the DODAG that the DIO belongs to. + * @param[in] dio The @p DIO packet. + * @param[in] src The address of the sender. + * @param[in] len The length of the whole DIO packet. + * @param[in] is_new Whether the DIO belongs to an existing or newly created DODAG. + * + * @retval True on success. + * @retval False otherwise. + */ +static bool _update_dodag_from_DIO(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv6_addr_t *src, + uint16_t len, bool is_new) +{ + gnrc_rpl_dodag_t *dodag = &inst->dodag; + gnrc_rpl_parent_t *parent = NULL; + + if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { + DEBUG("RPL: Could not allocate new parent.\n"); + return false; + } + + /* gnrc_rpl_parent_add_by_addr should have set this already */ + assert(parent != NULL); + + if (is_new) { + gnrc_rpl_delay_dao(dodag); + + uint32_t interval_min = 1 << dodag->dio_min; + uint8_t interval_max = dodag->dio_interval_doubl; + trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG, + interval_min, interval_max, dodag->dio_redun); + } + else { + trickle_increment_counter(&dodag->trickle); + } + + parent->rank = byteorder_ntohs(dio->rank); + gnrc_rpl_parent_update(dodag, parent); + + /* sender of incoming DIO is not preferred parent of mine (anymore) */ + if (parent != dodag->parents) { + if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) + && (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) { + trickle_reset_timer(&dodag->trickle); + } + return false; + } + + if (!_handle_DIO_opts(inst, dio, src, len, is_new)) { + DEBUG("RPL: Error encountered during DIO option parsing\n"); + return false; + } + + if (is_new) { + /* if there was no address created manually or by a PIO on the interface, + * leave this DODAG */ + gnrc_netif_t *netif = gnrc_netif_get_by_pid(dodag->iface); + if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) { + DEBUG("RPL: no IPv6 address configured on interface %i to match the " + "given dodag id: %s\n", netif->pid, + ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)); ); + return false; + } + } + + if (parent->dtsn != dio->dtsn) { + gnrc_rpl_delay_dao(dodag); + } + + parent->dtsn = dio->dtsn; + dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; + dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; + dodag->version = dio->version_number; + + return true; +} + /** * @brief Handles a received DIO message for a new DODAG. * @@ -795,8 +874,6 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker ipv6_addr_t *src, uint16_t len) { gnrc_netif_t *netif; - gnrc_rpl_dodag_t *dodag; - gnrc_rpl_parent_t *parent = NULL; if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) { DEBUG("RPL: ignore INFINITE_RANK DIO when we are not yet part of this DODAG\n"); @@ -817,44 +894,14 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid); - dodag = &inst->dodag; - DEBUG("RPL: Joined DODAG (%s).\n", - ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str))); + ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)); ); - if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { - DEBUG("RPL: Could not allocate new parent.\n"); + if (!_update_dodag_from_DIO(inst, dio, src, len, true)) { + DEBUG("RPL: remove DODAG.\n"); gnrc_rpl_instance_remove(inst); - return; } - gnrc_rpl_delay_dao(dodag); - uint32_t interval_min = 1 << dodag->dio_min; - uint8_t interval_max = dodag->dio_interval_doubl; - trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG, - interval_min, interval_max, dodag->dio_redun); - - parent->rank = byteorder_ntohs(dio->rank); - gnrc_rpl_parent_update(dodag, parent); - - if (!_handle_DIO_opts(inst, dio, src, len, true)) { - gnrc_rpl_instance_remove(inst); - return; - } - - /* if there was no address created manually or by a PIO on the interface, - * leave this DODAG */ - if (gnrc_netif_ipv6_addr_match(netif, &dio->dodag_id) < 0) { - DEBUG("RPL: no IPv6 address configured on interface %i to match the " - "given dodag id: %s\n", netif->pid, - ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str))); - gnrc_rpl_instance_remove(inst); - return; - } - - dodag->version = dio->version_number; - dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; - dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; } /** @@ -914,47 +961,7 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio return; } - gnrc_rpl_parent_t *parent = NULL; - - if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) { - DEBUG("RPL: Could not allocate new parent.\n"); - return; - } - - /* gnrc_rpl_parent_add_by_addr should have set this already */ - assert(parent != NULL); - - trickle_increment_counter(&dodag->trickle); - - parent->rank = byteorder_ntohs(dio->rank); - - gnrc_rpl_parent_update(dodag, parent); - - /* sender of incoming DIO is not a parent of mine (anymore) and has an INFINITE rank - and I have a rank != INFINITE_RANK */ - if (parent->state == GNRC_RPL_PARENT_UNUSED) { - if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) - && (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) { - trickle_reset_timer(&dodag->trickle); - } - return; - } - - /* incoming DIO is from pref. parent */ - if (parent == dodag->parents) { - if (parent->dtsn != dio->dtsn) { - gnrc_rpl_delay_dao(dodag); - } - parent->dtsn = dio->dtsn; - dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT; - dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK; - - if (!_handle_DIO_opts(inst, dio, src, len, false)) { - DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n"); - gnrc_rpl_instance_remove(inst); - return; - } - } + _update_dodag_from_DIO(inst, dio, src, len, false); } void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, From 947141db469c26c2dd5c37617e105b650548957c Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Tue, 1 Jul 2025 19:21:24 +0200 Subject: [PATCH 6/7] gnrc/rpl/control_messages: `_ip_addr_str` fn --- .../routing/rpl/gnrc_rpl_control_messages.c | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index d4c4b6346d..fef27847b6 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -512,6 +512,11 @@ static inline uint32_t _sec_to_ms(uint32_t sec) } } +static inline char *_ip_addr_str(ipv6_addr_t *addr) +{ + return ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)); +} + /** @todo allow target prefixes in target options to be of variable length */ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt, uint16_t len, @@ -638,8 +643,7 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt first_target = target; } - DEBUG("RPL: adding FT entry %s/%d\n", - ipv6_addr_to_str(addr_str, &(target->target), (unsigned)sizeof(addr_str)), + DEBUG("RPL: adding FT entry %s/%d\n", _ip_addr_str(&(target->target)), target->prefix_length); gnrc_ipv6_nib_ft_del(&(target->target), target->prefix_length); @@ -660,8 +664,7 @@ static bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt } do { - DEBUG("RPL: updating FT entry %s/%d\n", - ipv6_addr_to_str(addr_str, &(first_target->target), sizeof(addr_str)), + DEBUG("RPL: updating FT entry %s/%d\n", _ip_addr_str(&(first_target->target)), first_target->prefix_length); gnrc_ipv6_nib_ft_del(&(first_target->target), @@ -843,8 +846,7 @@ static bool _update_dodag_from_DIO(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *di gnrc_netif_t *netif = gnrc_netif_get_by_pid(dodag->iface); if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) { DEBUG("RPL: no IPv6 address configured on interface %i to match the " - "given dodag id: %s\n", netif->pid, - ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)); ); + "given dodag id: %s\n", netif->pid, _ip_addr_str(&(dio->dodag_id))); return false; } } @@ -894,8 +896,7 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid); - DEBUG("RPL: Joined DODAG (%s).\n", - ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)); ); + DEBUG("RPL: Joined DODAG (%s).\n", _ip_addr_str(&(dio->dodag_id))); if (!_update_dodag_from_DIO(inst, dio, src, len, true)) { DEBUG("RPL: remove DODAG.\n"); @@ -1097,7 +1098,7 @@ void gnrc_rpl_send_DAO(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination, uint if (ipv6_addr_is_global(&fte.dst) && !ipv6_addr_is_unspecified(&fte.next_hop)) { DEBUG("RPL: Send DAO - building target %s/%d\n", - ipv6_addr_to_str(addr_str, &fte.dst, sizeof(addr_str)), fte.dst_len); + _ip_addr_str(&fte.dst), fte.dst_len); if ((pkt = _dao_target_build(pkt, &fte.dst, fte.dst_len)) == NULL) { DEBUG("RPL: Send DAO - no space left in packet buffer\n"); @@ -1107,8 +1108,7 @@ void gnrc_rpl_send_DAO(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination, uint } /* add own address */ - DEBUG("RPL: Send DAO - building target %s/128\n", - ipv6_addr_to_str(addr_str, me, sizeof(addr_str))); + DEBUG("RPL: Send DAO - building target %s/128\n", _ip_addr_str(me)); if ((pkt = _dao_target_build(pkt, me, IPV6_ADDR_BIT_LEN)) == NULL) { DEBUG("RPL: Send DAO - no space left in packet buffer\n"); return; @@ -1248,10 +1248,7 @@ void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src /* check if the D flag is set before accessing the DODAG id */ if ((dao->k_d_flags & GNRC_RPL_DAO_D_BIT)) { if (memcmp(&dodag->dodag_id, (ipv6_addr_t *)(dao + 1), sizeof(ipv6_addr_t)) != 0) { - DEBUG("RPL: DAO with unknown DODAG id (%s)\n", ipv6_addr_to_str(addr_str, - (ipv6_addr_t *)(dao + - 1), - sizeof(addr_str))); + DEBUG("RPL: DAO with unknown DODAG id (%s)\n", _ip_addr_str((ipv6_addr_t *)(dao + 1))); return; } opts = (gnrc_rpl_opt_t *)(((uint8_t *)opts) + sizeof(ipv6_addr_t)); @@ -1314,10 +1311,8 @@ void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, kernel_pid_t iface, ipv6 /* check if the D flag is set before accessing the DODAG id */ if ((dao_ack->d_reserved & GNRC_RPL_DAO_ACK_D_BIT)) { if (memcmp(&dodag->dodag_id, (ipv6_addr_t *)(dao_ack + 1), sizeof(ipv6_addr_t)) != 0) { - DEBUG("RPL: DAO-ACK with unknown DODAG id (%s)\n", ipv6_addr_to_str(addr_str, - (ipv6_addr_t *)( - dao_ack + 1), - sizeof(addr_str))); + DEBUG("RPL: DAO-ACK with unknown DODAG id (%s)\n", + _ip_addr_str((ipv6_addr_t *)(dao_ack + 1))); return; } } From a461e5c41d614b7aa649dd3d314740139a698238 Mon Sep 17 00:00:00 2001 From: Elena Frank Date: Tue, 26 Aug 2025 10:54:31 +0200 Subject: [PATCH 7/7] gnrc/rpl/control_messages: doc `gnrc_rpl_recv_DIO` --- sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index fef27847b6..52dd845935 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -965,6 +965,15 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio _update_dodag_from_DIO(inst, dio, src, len, false); } +/** + * @brief Handles a received DIO message. + * + * @param[in] dio The received @p DIO packet. + * @param[in] iface The interface that the DIO was received on. + * @param[in] src The source address of the received packet. + * @param[in] dst The destination address of the received packet. + * @param[in] len The length of the DIO packet. + */ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, uint16_t len) {