Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rpl_policy.c Source File

rpl_policy.c

00001 /*
00002  * Copyright (c) 2015-2017, 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/address.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 /* TODO - application API to control when to join new instances / DODAGs
00038  *
00039  * Eg, allow application to ignore local DODAGs, or specify known instance IDs,
00040  * select on something in the configuration...
00041  *
00042  * See RFC 6550 18.6. Policy
00043  */
00044 bool rpl_policy_join_instance(rpl_domain_t *domain, uint8_t instance_id, const uint8_t *dodagid)
00045 {
00046     (void)domain;
00047     (void)instance_id;
00048     (void)dodagid;
00049 
00050     /* And that will do for now. */
00051     return true;
00052 }
00053 
00054 bool rpl_policy_join_dodag(rpl_domain_t *domain, uint8_t g_mop_prf, uint8_t instance_id, const uint8_t *addr)
00055 {
00056     (void)domain;
00057     (void)g_mop_prf;
00058     (void)instance_id;
00059     (void)addr;
00060 
00061     /* And that will do for now. */
00062     return true;
00063 }
00064 
00065 bool rpl_policy_join_config(rpl_domain_t *domain, const rpl_dodag_conf_t *conf, bool *leaf_only)
00066 {
00067     (void)domain;
00068     (void)conf;
00069     (void)leaf_only;
00070 
00071     /* Sanity checks */
00072     if (conf->min_hop_rank_increase == 0) {
00073         return false;
00074     }
00075 
00076     /* We don't support authentication */
00077     if (conf->authentication) {
00078         return false;
00079     }
00080 
00081     /* We're okay with DODAGs with unrecognised objectives - core will join as leaf using OF0 if we do nothing*/
00082 #if 0
00083     /* To reject unknowns: */
00084     if (!rpl_objective_lookup(conf->objective_code_point)) {
00085         return false;
00086     }
00087 #endif
00088 
00089     return true;
00090 }
00091 
00092 
00093 /*bool rpl_policy_join_unsupported_as_leaf(rpl_domain_t *domain)
00094 {
00095     return true;
00096 }*/
00097 
00098 bool rpl_policy_request_dao_acks(const rpl_domain_t *domain, uint8_t mop)
00099 {
00100     (void)domain;
00101     (void)mop;
00102 
00103     return true;
00104 }
00105 
00106 uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop)
00107 {
00108     (void)mop;
00109     ipv6_neighbour_cache_t *ncache = ipv6_neighbour_cache_by_interface_id(domain->non_storing_downstream_interface);
00110     if (ncache) {
00111         //Check here RE trans timeout
00112         if (ncache->retrans_timer > 2000) {
00113             uint32_t reTransTimer = ncache->retrans_timer / 100;
00114             if (reTransTimer > 0x7fff)
00115             {
00116                 return 0xffff;
00117             }
00118             return (uint16_t)reTransTimer*2;
00119         }
00120     }
00121 
00122     return 20; /* *100ms ticks = 2s */
00123 }
00124 
00125 /* Given the next-hop address from a source routing header, which interface,
00126  * if any, should we assume that next hop is on?
00127  */
00128 #define ETX_SRH_THRESHOLD 0x800 /* 8.8 fixed-point, so 4 */
00129 int8_t rpl_policy_srh_next_hop_interface(rpl_domain_t *domain, int8_t if_id, const uint8_t *next_hop)
00130 {
00131     if (domain->non_storing_downstream_interface != -1) {
00132         if_id = domain->non_storing_downstream_interface;
00133     }
00134 
00135     ipv6_neighbour_cache_t *ncache = ipv6_neighbour_cache_by_interface_id(if_id);
00136     ipv6_neighbour_t *n = ncache ? ipv6_neighbour_lookup(ncache, next_hop) : NULL;
00137     if (n && n->state == IP_NEIGHBOUR_UNREACHABLE) {
00138         tr_warn("Rejecting SRH to %s: neighbour unreachable", trace_ipv6(next_hop));
00139         goto reject;
00140     }
00141 
00142     uint16_t etx = ipv6_map_ip_to_ll_and_call_ll_addr_handler(NULL, if_id, n, next_hop, etx_read);
00143     if (etx > ETX_SRH_THRESHOLD) {
00144         tr_warn("Rejecting SRH to %s: etx = %x", trace_ipv6(next_hop), etx);
00145         goto reject;
00146     }
00147 
00148     return if_id;
00149 
00150 reject:
00151     /* If rejecting due to SRH or unreachable, we should do some sort of probe
00152      * to try to update state. This does the job. */
00153     if (n) {
00154         ipv6_neighbour_used(ncache, n);
00155     }
00156     return -1;
00157 }
00158 
00159 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)
00160 {
00161     (void)domain;
00162 
00163     ipv6_neighbour_cache_t *ncache = ipv6_neighbour_cache_by_interface_id(if_id);
00164     ipv6_neighbour_t *n = ncache ? ipv6_neighbour_lookup(ncache, next_hop) : NULL;
00165     uint16_t etx = ipv6_map_ip_to_ll_and_call_ll_addr_handler(NULL, if_id, n, next_hop, etx_read);
00166 
00167     if (etx == 0xFFFF) {
00168         return cost + 256;
00169     }
00170     if (etx > ETX_SRH_THRESHOLD) {
00171         return cost + 8;
00172     }
00173     if (!ipv6_neighbour_is_probably_reachable(ncache, n)) {
00174         return cost + 4;
00175     }
00176 
00177     return cost;
00178 }
00179 
00180 uint16_t rpl_policy_parent_selection_period(rpl_domain_t *domain)
00181 {
00182     (void)domain;
00183 
00184     return (10*60); /* seconds */
00185 }
00186 
00187 uint16_t rpl_policy_etx_hysteresis(rpl_domain_t *domain)
00188 {
00189     (void)domain;
00190 
00191     return 0x0080; /* 8.8 fixed-point, so 0.5 */
00192 }
00193 
00194 uint16_t rpl_policy_etx_change_parent_selection_delay(rpl_domain_t *domain)
00195 {
00196     (void)domain;
00197 
00198     return 30; /* seconds */
00199 }
00200 
00201 uint16_t rpl_policy_dio_parent_selection_delay(rpl_domain_t *domain)
00202 {
00203     (void)domain;
00204 
00205     return 15; /* seconds */
00206 }
00207 
00208 uint16_t rpl_policy_repair_initial_dis_delay(rpl_domain_t *domain)
00209 {
00210     (void)domain;
00211 
00212     return 10; /* seconds */
00213 }
00214 
00215 uint16_t rpl_policy_repair_maximum_dis_interval(rpl_domain_t *domain)
00216 {
00217     (void)domain;
00218 
00219     return 60*60; /* seconds = 1 hour */
00220 }
00221 
00222 uint_fast8_t rpl_policy_repair_dis_count(rpl_domain_t *domain)
00223 {
00224     (void)domain;
00225 
00226     return 6;
00227 }
00228 
00229 uint_fast8_t rpl_policy_repair_poison_count(rpl_domain_t *domain)
00230 {
00231     (void)domain;
00232 
00233     return 2;
00234 }
00235 
00236 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)
00237 {
00238     (void)domain;
00239     (void)seconds_since_last_dao_trigger;
00240 
00241     /* Trigger a DAO refresh after a number of errors proportional to the network size */
00242     return errors_since_last_dao_trigger > 2 * targets;
00243 }
00244 
00245 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)
00246 {
00247     (void)domain;
00248     (void)addr;
00249     (void)source;
00250     (void)data;
00251     (void)descriptor_out;
00252 
00253     return false;
00254 }
00255 
00256 bool rpl_policy_target_descriptor_for_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t *descriptor_out)
00257 {
00258     (void)domain;
00259     (void)addr;
00260     (void)descriptor_out;
00261 
00262     return false;
00263 }
00264 
00265 uint16_t rpl_policy_of0_stretch_of_rank(const rpl_domain_t *domain)
00266 {
00267     (void)domain;
00268 
00269     return 0;
00270 }
00271 
00272 uint_fast8_t rpl_policy_of0_rank_factor(const rpl_domain_t *domain)
00273 {
00274     (void)domain;
00275 
00276     return 1;
00277 }
00278 
00279 bool rpl_policy_of0_dodag_preference_supersedes_grounded(const rpl_domain_t *domain)
00280 {
00281     (void)domain;
00282 
00283     return false;
00284 }
00285 
00286 uint_fast8_t rpl_policy_of0_max_backup_successors(const rpl_domain_t *domain)
00287 {
00288     (void)domain;
00289 
00290     return 1;
00291 }
00292 
00293 uint_fast8_t rpl_policy_mrhof_parent_set_size(const rpl_domain_t *domain)
00294 {
00295     (void)domain;
00296 
00297     return 3;
00298 }
00299 
00300 uint16_t rpl_policy_mrhof_max_rank_stretch_for_extra_parents(const rpl_domain_t *domain)
00301 {
00302     (void)domain;
00303 
00304     /* Conservative - will allow some backup, but not an extra hop */
00305     return 64;
00306 }
00307 
00308 uint16_t rpl_policy_mrhof_max_link_metric(const rpl_domain_t *domain)
00309 {
00310     (void)domain;
00311 
00312     return 512;
00313 }
00314 
00315 uint16_t rpl_policy_mrhof_parent_switch_threshold(const rpl_domain_t *domain)
00316 {
00317     (void)domain;
00318 
00319     return 192;
00320 }
00321 
00322 
00323 #ifdef RPL_STRUCTURES_H_
00324 #error "rpl_structures.h should not be included by rpl_policy.c"
00325 #endif
00326 
00327 #endif /* HAVE_RPL */