Skip to content

Commit f618e59

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 ca2f13f commit f618e59

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
@@ -782,6 +782,85 @@ static bool _handle_DIO_opts(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv
782782
return true;
783783
}
784784

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

801878
if (byteorder_ntohs(dio->rank) == GNRC_RPL_INFINITE_RANK) {
802879
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
817894

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

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

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

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

860907
/**
@@ -914,47 +961,7 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio
914961
return;
915962
}
916963

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

960967
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)