@@ -781,6 +781,85 @@ static bool _handle_DIO_opts(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ipv
781
781
return true;
782
782
}
783
783
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
+
784
863
/**
785
864
* @brief Handles a received DIO message for a new DODAG.
786
865
*
@@ -794,8 +873,6 @@ void _recv_DIO_for_new_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio_t *dio, ker
794
873
ipv6_addr_t * src , uint16_t len )
795
874
{
796
875
gnrc_netif_t * netif ;
797
- gnrc_rpl_dodag_t * dodag ;
798
- gnrc_rpl_parent_t * parent = NULL ;
799
876
800
877
if (byteorder_ntohs (dio -> rank ) == GNRC_RPL_INFINITE_RANK ) {
801
878
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
816
893
817
894
gnrc_rpl_dodag_init (inst , & dio -> dodag_id , netif -> pid );
818
895
819
- dodag = & inst -> dodag ;
820
-
821
896
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 )); );
835
898
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" );
840
901
gnrc_rpl_instance_remove (inst );
841
- return ;
842
902
}
843
903
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 ;
857
904
}
858
905
859
906
/**
@@ -913,47 +960,7 @@ static void _recv_DIO_for_existing_dodag(gnrc_rpl_instance_t *inst, gnrc_rpl_dio
913
960
return ;
914
961
}
915
962
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);
957
964
}
958
965
959
966
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