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