Skip to content

Commit 228357f

Browse files
committed
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.
1 parent 4b32e43 commit 228357f

File tree

1 file changed

+83
-76
lines changed

1 file changed

+83
-76
lines changed

sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c

Lines changed: 83 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,85 @@ static bool _handle_DIO_opts(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv
781781
return true;
782782
}
783783

784+
/**
785+
* @brief Updates a DODAG with the info from a received DIO packet.
786+
*
787+
* @param[in] inst The @p RPL instance of the DODAG that the DIO belongs to.
788+
* @param[in] dio The @p DIO packet.
789+
* @param[in] src The address of the sender.
790+
* @param[in] len The length of the whole DIO packet.
791+
* @param[in] is_new Whether the DIO belongs to an existing or newly created DODAG.
792+
*
793+
* @retval True on success.
794+
* @retval False otherwise.
795+
*/
796+
static bool _update_dodag_from_DIO(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv6_addr_t *src,
797+
uint16_t len, bool is_new)
798+
{
799+
gnrc_rpl_dodag_t *dodag = &inst->dodag;
800+
gnrc_rpl_parent_t *parent = NULL;
801+
802+
if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) {
803+
DEBUG("RPL: Could not allocate new parent.\n");
804+
return false;
805+
}
806+
807+
/* gnrc_rpl_parent_add_by_addr should have set this already */
808+
assert(parent != NULL);
809+
810+
if (is_new) {
811+
gnrc_rpl_delay_dao(dodag);
812+
813+
uint32_t interval_min = 1 << dodag->dio_min;
814+
uint8_t interval_max = dodag->dio_interval_doubl;
815+
trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG,
816+
interval_min, interval_max, dodag->dio_redun);
817+
}
818+
else {
819+
trickle_increment_counter(&dodag->trickle);
820+
}
821+
822+
parent->rank = byteorder_ntohs(dio->rank);
823+
gnrc_rpl_parent_update(dodag, parent);
824+
825+
/* sender of incoming DIO is not preferred parent of mine (anymore) */
826+
if (parent != dodag->parents) {
827+
if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK)
828+
&& (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) {
829+
trickle_reset_timer(&dodag->trickle);
830+
}
831+
return false;
832+
}
833+
834+
if (!_handle_DIO_opts(inst, dio, src, len, is_new)) {
835+
DEBUG("RPL: Error encountered during DIO option parsing\n");
836+
return false;
837+
}
838+
839+
if (is_new) {
840+
/* if there was no address created manually or by a PIO on the interface,
841+
* leave this DODAG */
842+
gnrc_netif_t *netif = gnrc_netif_get_by_pid(dodag->iface);
843+
if (gnrc_netif_ipv6_addr_match(netif, &dodag->dodag_id) < 0) {
844+
DEBUG("RPL: no IPv6 address configured on interface %i to match the "
845+
"given dodag id: %s\n", netif->pid,
846+
ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)); );
847+
return false;
848+
}
849+
}
850+
851+
if (parent->dtsn != dio->dtsn) {
852+
gnrc_rpl_delay_dao(dodag);
853+
}
854+
855+
parent->dtsn = dio->dtsn;
856+
dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT;
857+
dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK;
858+
dodag->version = dio->version_number;
859+
860+
return true;
861+
}
862+
784863
/**
785864
* @brief Handles a received DIO message for a new DODAG.
786865
*
@@ -794,8 +873,6 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker
794873
ipv6_addr_t *src, uint16_t len)
795874
{
796875
gnrc_netif_t *netif;
797-
gnrc_rpl_dodag_t *dodag;
798-
gnrc_rpl_parent_t *parent = NULL;
799876

800877
if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) {
801878
DEBUG("RPL: ignore INFINITE_RANK DIO when we are not yet part of this DODAG\n");
@@ -816,44 +893,14 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker
816893

817894
gnrc_rpl_dodag_init(inst, &dio->dodag_id, netif->pid);
818895

819-
dodag = &inst->dodag;
820-
821896
DEBUG("RPL: Joined DODAG (%s).\n",
822-
ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)));
823-
824-
if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) {
825-
DEBUG("RPL: Could not allocate new parent.\n");
826-
gnrc_rpl_instance_remove(inst);
827-
return;
828-
}
829-
830-
gnrc_rpl_delay_dao(dodag);
831-
uint32_t interval_min = 1 << dodag->dio_min;
832-
uint8_t interval_max = dodag->dio_interval_doubl;
833-
trickle_start(gnrc_rpl_pid, &dodag->trickle, GNRC_RPL_MSG_TYPE_TRICKLE_MSG,
834-
interval_min, interval_max, dodag->dio_redun);
897+
ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)); );
835898

836-
parent->rank = byteorder_ntohs(dio->rank);
837-
gnrc_rpl_parent_update(dodag, parent);
838-
839-
if (!_handle_DIO_opts(inst, dio, src, len, true)) {
899+
if (!_update_dodag_from_DIO(inst, dio, src, len, true)) {
900+
DEBUG("RPL: remove DODAG.\n");
840901
gnrc_rpl_instance_remove(inst);
841-
return;
842902
}
843903

844-
/* if there was no address created manually or by a PIO on the interface,
845-
* leave this DODAG */
846-
if (gnrc_netif_ipv6_addr_match(netif, &dio->dodag_id) < 0) {
847-
DEBUG("RPL: no IPv6 address configured on interface %i to match the "
848-
"given dodag id: %s\n", netif->pid,
849-
ipv6_addr_to_str(addr_str, &(dio->dodag_id), sizeof(addr_str)));
850-
gnrc_rpl_instance_remove(inst);
851-
return;
852-
}
853-
854-
dodag->version = dio->version_number;
855-
dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT;
856-
dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK;
857904
}
858905

859906
/**
@@ -913,47 +960,7 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio
913960
return;
914961
}
915962

916-
gnrc_rpl_parent_t *parent = NULL;
917-
918-
if (!gnrc_rpl_parent_add_by_addr(dodag, src, &parent) && (parent == NULL)) {
919-
DEBUG("RPL: Could not allocate new parent.\n");
920-
return;
921-
}
922-
923-
/* gnrc_rpl_parent_add_by_addr should have set this already */
924-
assert(parent != NULL);
925-
926-
trickle_increment_counter(&dodag->trickle);
927-
928-
parent->rank = byteorder_ntohs(dio->rank);
929-
930-
gnrc_rpl_parent_update(dodag, parent);
931-
932-
/* sender of incoming DIO is not a parent of mine (anymore) and has an INFINITE rank
933-
and I have a rank != INFINITE_RANK */
934-
if (parent->state == GNRC_RPL_PARENT_UNUSED) {
935-
if ((byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK)
936-
&& (dodag->my_rank != GNRC_RPL_INFINITE_RANK)) {
937-
trickle_reset_timer(&dodag->trickle);
938-
}
939-
return;
940-
}
941-
942-
/* incoming DIO is from pref. parent */
943-
if (parent == dodag->parents) {
944-
if (parent->dtsn != dio->dtsn) {
945-
gnrc_rpl_delay_dao(dodag);
946-
}
947-
parent->dtsn = dio->dtsn;
948-
dodag->grounded = dio->g_mop_prf >> GNRC_RPL_GROUNDED_SHIFT;
949-
dodag->prf = dio->g_mop_prf & GNRC_RPL_PRF_MASK;
950-
951-
if (!_handle_DIO_opts(inst, dio, src, len, false)) {
952-
DEBUG("RPL: Error encountered during DIO option parsing - remove DODAG\n");
953-
gnrc_rpl_instance_remove(inst);
954-
return;
955-
}
956-
}
963+
_update_dodag_from_DIO(inst, dio, src, len, false);
957964
}
958965

959966
void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst,

0 commit comments

Comments
 (0)