Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rpl_policy.c Source File

rpl_policy.c

00001 /*
00002  * Copyright (c) 2015-2019, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "nsconfig.h"
00019 
00020 #ifdef HAVE_RPL
00021 
00022 #include "ns_types.h"
00023 #include "ns_trace.h"
00024 
00025 #include "net_interface.h"
00026 
00027 #include "Core/include/ns_address_internal.h"
00028 #include "Service_Libs/etx/etx.h"
00029 #include "Common_Protocols/ipv6_resolution.h"
00030 #include "ipv6_stack/ipv6_routing_table.h"
00031 
00032 #include "RPL/rpl_objective.h"
00033 #include "RPL/rpl_policy.h"
00034 
00035 #define TRACE_GROUP "RPLy"
00036 
00037 static bool rpl_policy_parent_confirmation_req = false;
00038 static int8_t rpl_policy_dao_retry_count_conf = 0;
00039 static int16_t rpl_policy_dao_initial_timeout_conf = 20; // Default is 2 seconds 100ms ticks
00040 static uint16_t rpl_policy_dio_validity_period_hysteresis = 0x0180; //Fixed Point 1.5
00041 static uint8_t rpl_policy_multicast_config_min_advertisment_count = 0;
00042 
00043 
00044 /* TODO - application API to control when to join new instances / DODAGs
00045  *
00046  * Eg, allow application to ignore local DODAGs, or specify known instance IDs,
00047  * select on something in the configuration...
00048  *
00049  * See RFC 6550 18.6. Policy
00050  */
00051 bool rpl_policy_join_instance(rpl_domain_t *domain, uint8_t instance_id, const uint8_t *dodagid)
00052 {
00053     (void)domain;
00054     (void)instance_id;
00055     (void)dodagid;
00056 
00057     /* And that will do for now. */
00058     return true;
00059 }
00060 
00061 bool rpl_policy_join_dodag(rpl_domain_t *domain, uint8_t g_mop_prf, uint8_t instance_id, const uint8_t *addr)
00062 {
00063     (void)domain;
00064     (void)g_mop_prf;
00065     (void)instance_id;
00066     (void)addr;
00067 
00068     /* And that will do for now. */
00069     return true;
00070 }
00071 
00072 bool rpl_policy_join_config(rpl_domain_t *domain, const rpl_dodag_conf_t *conf, bool *leaf_only)
00073 {
00074     (void)domain;
00075     (void)conf;
00076     (void)leaf_only;
00077 
00078     /* Sanity checks */
00079     if (conf->min_hop_rank_increase == 0) {
00080         return false;
00081     }
00082 
00083     /* We don't support authentication */
00084     if (conf->authentication) {
00085         return false;
00086     }
00087 
00088     /* We're okay with DODAGs with unrecognised objectives - core will join as leaf using OF0 if we do nothing*/
00089 #if 0
00090     /* To reject unknowns: */
00091     if (!rpl_objective_lookup(conf->objective_code_point)) {
00092         return false;
00093     }
00094 #endif
00095 
00096     return true;
00097 }
00098 
00099 
00100 /*bool rpl_policy_join_unsupported_as_leaf(rpl_domain_t *domain)
00101 {
00102     return true;
00103 }*/
00104 
00105 bool rpl_policy_request_dao_acks(const rpl_domain_t *domain, uint8_t mop)
00106 {
00107     (void)domain;
00108     (void)mop;
00109 
00110     return true;
00111 }
00112 
00113 void rpl_policy_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
00114 {
00115     rpl_policy_dao_initial_timeout_conf = timeout_in_ms;
00116 }
00117 
00118 uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop)
00119 {
00120     (void)mop;
00121     ipv6_neighbour_cache_t *ncache = ipv6_neighbour_cache_by_interface_id(domain->non_storing_downstream_interface);
00122     if (ncache) {
00123         //Check here RE trans timeout
00124         if (ncache->retrans_timer > 2000) {
00125             uint32_t reTransTimer = ncache->retrans_timer / 100;
00126             if (reTransTimer > 0x7fff) {
00127                 return 0xffff;
00128             }
00129             return (uint16_t)reTransTimer * 2;
00130         }
00131     }
00132 
00133     return rpl_policy_dao_initial_timeout_conf;
00134 }
00135 
00136 
00137 void rpl_policy_set_dao_retry_count(uint8_t count)
00138 {
00139     rpl_policy_dao_retry_count_conf = count;
00140 }
00141 
00142 int8_t rpl_policy_dao_retry_count()
00143 {
00144     return rpl_policy_dao_retry_count_conf;
00145 }
00146 
00147 /* Given the next-hop address from a source routing header, which interface,
00148  * if any, should we assume that next hop is on?
00149  */
00150 #define ETX_SRH_THRESHOLD 0x800 /* 8.8 fixed-point, so 4 */
00151 int8_t rpl_policy_srh_next_hop_interface(rpl_domain_t *domain, int8_t if_id, const uint8_t *next_hop)
00152 {
00153     if (domain->non_storing_downstream_interface != -1) {
00154         if_id = domain->non_storing_downstream_interface;
00155     }
00156 
00157     ipv6_neighbour_cache_t *ncache = ipv6_neighbour_cache_by_interface_id(if_id);
00158     ipv6_neighbour_t *n = ncache ? ipv6_neighbour_lookup(ncache, next_hop) : NULL;
00159     if (n && n->state == IP_NEIGHBOUR_UNREACHABLE) {
00160         tr_warn("Rejecting SRH to %s: neighbour unreachable", trace_ipv6(next_hop));
00161         goto reject;
00162     }
00163 
00164     uint16_t etx = ipv6_map_ip_to_ll_and_call_ll_addr_handler(NULL, if_id, n, next_hop, etx_read);
00165     if (etx > ETX_SRH_THRESHOLD) {
00166         tr_warn("Rejecting SRH to %s: etx = %x", trace_ipv6(next_hop), etx);
00167         goto reject;
00168     }
00169 
00170     return if_id;
00171 
00172 reject:
00173     /* If rejecting due to SRH or unreachable, we should do some sort of probe
00174      * to try to update state. This does the job. */
00175     if (n) {
00176         ipv6_neighbour_used(ncache, n);
00177     }
00178     return -1;
00179 }
00180 
00181 uint16_t rpl_policy_modify_downward_cost_to_root_neighbour(rpl_domain_t *domain, int8_t if_id, const uint8_t *next_hop, uint16_t cost)
00182 {
00183     (void)domain;
00184 
00185     ipv6_neighbour_cache_t *ncache = ipv6_neighbour_cache_by_interface_id(if_id);
00186     ipv6_neighbour_t *n = ncache ? ipv6_neighbour_lookup(ncache, next_hop) : NULL;
00187     uint16_t etx = ipv6_map_ip_to_ll_and_call_ll_addr_handler(NULL, if_id, n, next_hop, etx_read);
00188 
00189     if (etx == 0xFFFF) {
00190         return cost + 256;
00191     }
00192     if (etx > ETX_SRH_THRESHOLD) {
00193         return cost + 8;
00194     }
00195     if (!ipv6_neighbour_is_probably_reachable(ncache, n)) {
00196         return cost + 4;
00197     }
00198 
00199     return cost;
00200 }
00201 
00202 uint16_t rpl_policy_parent_selection_period(rpl_domain_t *domain)
00203 {
00204     (void)domain;
00205 
00206     return (10 * 60); /* seconds */
00207 }
00208 
00209 uint16_t rpl_policy_etx_hysteresis(rpl_domain_t *domain)
00210 {
00211     (void)domain;
00212 
00213     return 0x0080; /* 8.8 fixed-point, so 0.5 */
00214 }
00215 
00216 uint16_t rpl_policy_dio_validity_period(rpl_domain_t *domain)
00217 {
00218     (void)domain;
00219 
00220     return rpl_policy_dio_validity_period_hysteresis; /* Fixed Point */
00221 }
00222 
00223 void rpl_policy_set_dio_validity_period(rpl_domain_t *domain, uint16_t fixed_point)
00224 {
00225     (void)domain;
00226 
00227     rpl_policy_dio_validity_period_hysteresis = fixed_point; /* Fixed Point */
00228 }
00229 
00230 uint16_t rpl_policy_etx_change_parent_selection_delay(rpl_domain_t *domain)
00231 {
00232     (void)domain;
00233 
00234     return 30; /* seconds */
00235 }
00236 
00237 uint16_t rpl_policy_dio_parent_selection_delay(rpl_domain_t *domain)
00238 {
00239     (void)domain;
00240 
00241     return 15; /* seconds */
00242 }
00243 
00244 uint16_t rpl_policy_repair_initial_dis_delay(rpl_domain_t *domain)
00245 {
00246     (void)domain;
00247 
00248     return 10; /* seconds */
00249 }
00250 
00251 uint16_t rpl_policy_repair_maximum_dis_interval(rpl_domain_t *domain)
00252 {
00253     (void)domain;
00254 
00255     return 60 * 60; /* seconds = 1 hour */
00256 }
00257 
00258 uint_fast8_t rpl_policy_repair_dis_count(rpl_domain_t *domain)
00259 {
00260     (void)domain;
00261 
00262     return 6;
00263 }
00264 
00265 uint_fast8_t rpl_policy_repair_poison_count(rpl_domain_t *domain)
00266 {
00267     (void)domain;
00268 
00269     return 2;
00270 }
00271 
00272 bool rpl_policy_dao_trigger_after_srh_error(rpl_domain_t *domain, uint32_t seconds_since_last_dao_trigger, uint16_t errors_since_last_dao_trigger, uint_fast16_t targets)
00273 {
00274     (void)domain;
00275     (void)seconds_since_last_dao_trigger;
00276 
00277     /* Trigger a DAO refresh after a number of errors proportional to the network size */
00278     return errors_since_last_dao_trigger > 2 * targets;
00279 }
00280 
00281 bool rpl_policy_target_descriptor_for_own_address(rpl_domain_t *domain, const uint8_t addr[16], if_address_source_t source, void *data, uint32_t *descriptor_out)
00282 {
00283     (void)domain;
00284     (void)addr;
00285     (void)source;
00286     (void)data;
00287     (void)descriptor_out;
00288 
00289     return false;
00290 }
00291 
00292 bool rpl_policy_target_descriptor_for_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t *descriptor_out)
00293 {
00294     (void)domain;
00295     (void)addr;
00296     (void)descriptor_out;
00297 
00298     return false;
00299 }
00300 
00301 uint16_t rpl_policy_of0_stretch_of_rank(const rpl_domain_t *domain)
00302 {
00303     (void)domain;
00304 
00305     return 0;
00306 }
00307 
00308 uint_fast8_t rpl_policy_of0_rank_factor(const rpl_domain_t *domain)
00309 {
00310     (void)domain;
00311 
00312     return 1;
00313 }
00314 
00315 bool rpl_policy_of0_dodag_preference_supersedes_grounded(const rpl_domain_t *domain)
00316 {
00317     (void)domain;
00318 
00319     return false;
00320 }
00321 
00322 uint_fast8_t rpl_policy_of0_max_backup_successors(const rpl_domain_t *domain)
00323 {
00324     (void)domain;
00325 
00326     return 1;
00327 }
00328 
00329 uint_fast8_t rpl_policy_mrhof_parent_set_size(const rpl_domain_t *domain)
00330 {
00331     (void)domain;
00332 
00333     return 3;
00334 }
00335 
00336 uint16_t rpl_policy_mrhof_max_rank_stretch_for_extra_parents(const rpl_domain_t *domain)
00337 {
00338     (void)domain;
00339 
00340     /* Conservative - will allow some backup, but not an extra hop */
00341     return 64;
00342 }
00343 
00344 uint16_t rpl_policy_mrhof_max_link_metric(const rpl_domain_t *domain)
00345 {
00346     (void)domain;
00347 
00348     return 512;
00349 }
00350 
00351 uint16_t rpl_policy_mrhof_parent_switch_threshold(const rpl_domain_t *domain)
00352 {
00353     (void)domain;
00354 
00355     return 192;
00356 }
00357 
00358 void rpl_policy_set_parent_confirmation_request(bool confirmation_requested)
00359 {
00360     rpl_policy_parent_confirmation_req = confirmation_requested;
00361 }
00362 
00363 
00364 bool rpl_policy_parent_confirmation_requested(void)
00365 {
00366     return rpl_policy_parent_confirmation_req;
00367 }
00368 
00369 uint8_t rpl_policy_dio_multicast_config_advertisment_min_count(void)
00370 {
00371     return rpl_policy_multicast_config_min_advertisment_count;
00372 }
00373 
00374 void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_count)
00375 {
00376     rpl_policy_multicast_config_min_advertisment_count = min_count;
00377 }
00378 
00379 
00380 #ifdef RPL_STRUCTURES_H_
00381 #error "rpl_structures.h should not be included by rpl_policy.c"
00382 #endif
00383 
00384 #endif /* HAVE_RPL */