Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ipv6_routing_table.h
00001 /* 00002 * Copyright (c) 2012, 2014-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 * ipv6_routing_table.h 00019 * 00020 * Implements Neighbour Cache 00021 */ 00022 00023 #ifndef IPV6_ROUTING_TABLE_H_ 00024 #define IPV6_ROUTING_TABLE_H_ 00025 00026 #include "ns_list.h" 00027 #include "Core/include/ns_address_internal.h" 00028 00029 /* Address Resolution and Neighbour Unreachablity Detection constants from 00030 * RFC 4861, updated by RFC 7048. 00031 */ 00032 #define MAX_MULTICAST_SOLICIT 3 00033 #define MAX_UNICAST_SOLICIT 5 00034 #define MARK_UNREACHABLE 3 00035 #define MAX_RETRANS_TIMER 60000 /* ms */ 00036 #define DELAY_FIRST_PROBE_TIME 5000 /* ms */ 00037 #define BACKOFF_MULTIPLE 3 00038 00039 /* RFC 6775 parameters */ 00040 #define TENTATIVE_NCE_LIFETIME 20 /* s */ 00041 00042 #define IPV6_ROUTE_DEFAULT_METRIC 128 00043 00044 /* XXX in the process of renaming this - it's really specifically the 00045 * IP Neighbour Cache but was initially called a routing table */ 00046 00047 typedef enum ip_neighbour_cache_state { 00048 IP_NEIGHBOUR_NEW, /* Not yet used; no LL addr, no NS sent */ 00049 IP_NEIGHBOUR_INCOMPLETE, 00050 IP_NEIGHBOUR_REACHABLE, 00051 IP_NEIGHBOUR_STALE, 00052 IP_NEIGHBOUR_DELAY, 00053 IP_NEIGHBOUR_PROBE, 00054 IP_NEIGHBOUR_UNREACHABLE 00055 } ip_neighbour_cache_state_t; 00056 00057 /* RFC 6775 types */ 00058 typedef enum ip_neighbour_cache_type { 00059 IP_NEIGHBOUR_GARBAGE_COLLECTIBLE, 00060 IP_NEIGHBOUR_REGISTERED, 00061 IP_NEIGHBOUR_TENTATIVE 00062 } ip_neighbour_cache_type_t; 00063 00064 typedef enum ipv6_route_src { 00065 ROUTE_ANY, /* Unspecified - use in lookups */ 00066 ROUTE_NONE, /* Only occurs in incomplete destination cache entries */ 00067 ROUTE_STATIC, 00068 ROUTE_LOOPBACK, 00069 ROUTE_USER, 00070 ROUTE_ARO, 00071 ROUTE_RADV, 00072 ROUTE_RPL_DIO, /* Explicitly advertised in DIO RIO */ 00073 ROUTE_RPL_DAO, /* Explicitly advertised in DAO, Storing mode */ 00074 ROUTE_RPL_DAO_SR, /* Explicitly advertised in DAO, Root Source Routes in Non-Storing mode */ 00075 ROUTE_RPL_SRH, /* Not in routing table - used in buffers to represent on-link inferred from SRH */ 00076 ROUTE_RPL_ROOT, /* Implicit route to DODAG root */ 00077 ROUTE_RPL_INSTANCE, /* Implicit instance-specific default upward route (not for general search) */ 00078 ROUTE_RPL_FWD_ERROR, /* Not in routing table - used in buffers to represent Forwarding-Error bounce */ 00079 ROUTE_MULTICAST, /* Not in routing table - used to represent multicast interface selection */ 00080 ROUTE_MPL, 00081 ROUTE_RIP, 00082 ROUTE_THREAD, 00083 ROUTE_THREAD_BORDER_ROUTER, 00084 ROUTE_THREAD_PROXIED_HOST, 00085 ROUTE_THREAD_PROXIED_DUA_HOST, 00086 ROUTE_THREAD_BBR, 00087 ROUTE_REDIRECT, /* Only occurs in destination cache */ 00088 ROUTE_MAX, 00089 } ipv6_route_src_t; 00090 00091 struct buffer; 00092 00093 typedef struct ipv6_neighbour { 00094 uint8_t ip_address[16]; /*!< neighbour IP address */ 00095 bool is_router: 1; 00096 bool from_redirect: 1; 00097 uint8_t retrans_count; 00098 ip_neighbour_cache_state_t state; 00099 ip_neighbour_cache_type_t type; 00100 addrtype_t ll_type; 00101 uint32_t timer; /* 100ms ticks */ 00102 uint32_t lifetime; /* seconds */ 00103 ns_list_link_t link; /*!< List link */ 00104 NS_LIST_HEAD_INCOMPLETE(struct buffer) queue; 00105 uint8_t ll_address[]; 00106 } ipv6_neighbour_t; 00107 00108 /* Neighbour Cache entries also store EUI-64 after ll_address if "recv_addr_reg" 00109 * is set for the cache. This is ADDR_EUI64_ZERO if unknown. 00110 */ 00111 #define ipv6_neighbour_eui64(ncache, entry) ((entry)->ll_address + (ncache)->max_ll_len) 00112 00113 typedef struct ipv6_route_info_cache { 00114 uint16_t metric; // interface metric 00115 uint8_t sources[ROUTE_MAX]; 00116 } ipv6_route_interface_info_t; 00117 00118 typedef struct ipv6_neighbour_cache { 00119 bool send_addr_reg : 1; 00120 bool recv_addr_reg : 1; 00121 bool send_nud_probes : 1; 00122 bool probe_avoided_routers : 1; 00123 bool recv_ns_aro : 1; 00124 bool recv_na_aro : 1; 00125 bool use_eui64_as_slla_in_aro : 1; 00126 bool omit_na_aro_success : 1; 00127 bool omit_na : 1; // except for ARO successes which have a separate flag 00128 int8_t interface_id; 00129 uint8_t max_ll_len; 00130 uint8_t gc_timer; 00131 uint16_t link_mtu; 00132 uint32_t retrans_timer; 00133 uint32_t reachable_time; 00134 // Interface specific information for route 00135 ipv6_route_interface_info_t route_if_info; 00136 //uint8_t num_entries; 00137 NS_LIST_HEAD (ipv6_neighbour_t, link) list; 00138 } ipv6_neighbour_cache_t; 00139 00140 /* Macros for formatting ipv6 addresses into strings for route printing. */ 00141 /* Initialize a string buffer for the ipv6 address */ 00142 #define ROUTE_PRINT_ADDR_STR_BUFFER_INIT(str) char str[41] = "<null>" 00143 /* Format and store ipv6 'addr' into 'str', and evaluate 'str' */ 00144 #define ROUTE_PRINT_ADDR_STR_FORMAT(str, addr) (ip6tos(addr, str), str) 00145 00146 /* Callback type for route print */ 00147 typedef void (route_print_fn_t)(const char *fmt, ...); 00148 00149 extern void ipv6_neighbour_cache_init(ipv6_neighbour_cache_t *cache, int8_t interface_id); 00150 extern void ipv6_neighbour_cache_flush(ipv6_neighbour_cache_t *cache); 00151 extern ipv6_neighbour_t *ipv6_neighbour_update(ipv6_neighbour_cache_t *cache, const uint8_t *address, bool solicited); 00152 extern void ipv6_neighbour_set_state(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, ip_neighbour_cache_state_t state); 00153 extern ipv6_neighbour_t *ipv6_neighbour_used(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry); 00154 extern ipv6_neighbour_t *ipv6_neighbour_lookup(ipv6_neighbour_cache_t *cache, const uint8_t *address); 00155 extern ipv6_neighbour_t *ipv6_neighbour_lookup_by_interface_id(int8_t interface_id, const uint8_t *address); 00156 extern ipv6_neighbour_t *ipv6_neighbour_lookup_or_create(ipv6_neighbour_cache_t *cache, const uint8_t *address); 00157 extern ipv6_neighbour_t *ipv6_neighbour_lookup_or_create_by_interface_id(int8_t interface_id, const uint8_t *address); 00158 extern void ipv6_neighbour_entry_remove(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry); 00159 extern bool ipv6_neighbour_is_probably_reachable(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *n); 00160 extern bool ipv6_neighbour_addr_is_probably_reachable(ipv6_neighbour_cache_t *cache, const uint8_t *address); 00161 extern bool ipv6_neighbour_ll_addr_match(const ipv6_neighbour_t *entry, addrtype_t ll_type, const uint8_t *ll_address); 00162 extern void ipv6_neighbour_invalidate_ll_addr(ipv6_neighbour_cache_t *cache, addrtype_t ll_type, const uint8_t *ll_address); 00163 extern void ipv6_neighbour_delete_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64); 00164 extern bool ipv6_neighbour_has_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64); 00165 extern void ipv6_neighbour_entry_update_unsolicited(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, addrtype_t type, const uint8_t *ll_address/*, bool tentative*/); 00166 extern ipv6_neighbour_t *ipv6_neighbour_update_unsolicited(ipv6_neighbour_cache_t *cache, const uint8_t *ip_address, addrtype_t ll_type, const uint8_t *ll_address); 00167 extern void ipv6_neighbour_reachability_confirmation(const uint8_t ip_address[__static 16], int8_t interface_id); 00168 extern void ipv6_neighbour_reachability_problem(const uint8_t ip_address[__static 16], int8_t interface_id); 00169 extern void ipv6_neighbour_update_from_na(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, uint8_t flags, addrtype_t ll_type, const uint8_t *ll_address); 00170 extern void ipv6_neighbour_cache_fast_timer(ipv6_neighbour_cache_t *cache, uint16_t ticks); 00171 extern void ipv6_neighbour_cache_slow_timer(ipv6_neighbour_cache_t *cache, uint8_t seconds); 00172 extern void ipv6_neighbour_cache_print(const ipv6_neighbour_cache_t *cache, route_print_fn_t *print_fn); 00173 extern void ipv6_router_gone(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry); 00174 extern int8_t ipv6_neighbour_set_current_max_cache(uint16_t max_cache); 00175 extern int8_t ipv6_destination_cache_configure(uint16_t max_entries, uint16_t short_term_threshold, uint16_t long_term_threshold, uint16_t lifetime); 00176 extern int8_t ipv6_neighbour_cache_configure(uint16_t max_entries, uint16_t short_term_threshold, uint16_t long_term_threshold, uint16_t lifetime); 00177 00178 /* Backwards compatibility with test app */ 00179 #define ROUTE_RPL_UP ROUTE_RPL_DIO 00180 #define ROUTE_RPL_DOWN ROUTE_RPL_DAO 00181 00182 typedef struct ipv6_route_info { 00183 ipv6_route_src_t source; 00184 uint8_t source_id; 00185 int8_t interface_id; 00186 uint16_t pmtu; 00187 void *info; // pointer to route provider's info 00188 uint8_t next_hop_addr[16]; 00189 } ipv6_route_info_t; 00190 00191 typedef struct ipv6_destination { 00192 /* Destination/path information */ 00193 uint8_t destination[16]; 00194 #ifdef HAVE_IPV6_ND 00195 uint8_t redirect_addr[16]; 00196 bool redirected; // we have a redirect in force 00197 #endif 00198 int8_t interface_id; // fixed if link-local destination, else variable and gets set from redirect interface and/or last_neighbour interface 00199 uint16_t refcount; 00200 uint16_t lifetime; // Life in GC calls, so 20s units 00201 #ifndef NO_IPV6_PMTUD 00202 uint16_t pmtu; // note this may be less than 1280 - upper layers may choose to send smaller based on this 00203 uint16_t pmtu_lifetime; // seconds 00204 #endif 00205 #ifndef NO_IP_FRAGMENT_TX 00206 uint32_t fragment_id; 00207 #endif 00208 ipv6_neighbour_t *last_neighbour; // last neighbour used (only for reachability confirmation) 00209 ns_list_link_t link; 00210 } ipv6_destination_t; 00211 00212 #ifndef NO_IPV6_PMTUD 00213 #define ipv6_destination_pmtu(d) ((d)->pmtu) 00214 #else 00215 #define ipv6_destination_pmtu(d) IPV6_MIN_LINK_MTU 00216 #endif 00217 00218 void ipv6_destination_cache_print(route_print_fn_t *print_fn); 00219 ipv6_destination_t *ipv6_destination_lookup_or_create(const uint8_t *address, int8_t interface_id); 00220 ipv6_destination_t *ipv6_destination_lookup_or_create_with_route(const uint8_t *address, int8_t interface_id, ipv6_route_info_t *route_out); 00221 void ipv6_destination_cache_timer(uint8_t ticks); 00222 #ifdef HAVE_IPV6_ND 00223 void ipv6_destination_redirect(const uint8_t *dest_addr, const uint8_t *sender_addr, const uint8_t *redirect_addr, int8_t interface_id, addrtype_t ll_type, const uint8_t *ll_address); 00224 #endif 00225 void ipv6_destination_cache_forced_gc(bool full_gc); 00226 00227 /* Combined Routing Table (RFC 4191) and Prefix List (RFC 4861) */ 00228 /* On-link prefixes have the on_link flag set and next_hop is unset */ 00229 typedef struct ipv6_route { 00230 uint8_t prefix_len; 00231 bool on_link: 1; 00232 bool search_skip: 1; 00233 bool probe: 1; 00234 bool info_autofree: 1; 00235 uint8_t metric; // 0x40 = RFC 4191 pref high, 0x80 = default, 0xC0 = RFC 4191 pref low 00236 ipv6_route_info_t info; 00237 uint32_t lifetime; // (seconds); 0xFFFFFFFF means permanent 00238 uint16_t probe_timer; 00239 ns_list_link_t link; 00240 uint8_t prefix[]; // variable length 00241 } ipv6_route_t; 00242 00243 /* Callback type for route predicate */ 00244 typedef bool ipv6_route_predicate_fn_t(const ipv6_route_info_t *route, bool valid); 00245 00246 /* Callbacks for route providers that dynamically compute next hop */ 00247 typedef bool ipv6_route_next_hop_fn_t(const uint8_t *dest, ipv6_route_info_t *route_info); 00248 00249 uint8_t ipv6_route_pref_to_metric(int_fast8_t pref); 00250 ipv6_route_t *ipv6_route_add(const uint8_t *prefix, uint8_t prefix_len, int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source, uint32_t lifetime, int_fast8_t pref); 00251 ipv6_route_t *ipv6_route_add_with_info(const uint8_t *prefix, uint8_t prefix_len, int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source, void *info, uint8_t source_id, uint32_t lifetime, int_fast8_t pref); 00252 ipv6_route_t *ipv6_route_add_metric(const uint8_t *prefix, uint8_t prefix_len, int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source, void *info, uint8_t source_id, uint32_t lifetime, uint8_t metric); 00253 ipv6_route_t *ipv6_route_lookup_with_info(const uint8_t *prefix, uint8_t prefix_len, int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source, void *info, int_fast16_t source_id); 00254 int_fast8_t ipv6_route_delete(const uint8_t *prefix, uint8_t prefix_len, int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source); 00255 int_fast8_t ipv6_route_delete_with_info(const uint8_t *prefix, uint8_t prefix_len, int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source, void *info, int_fast16_t source_id); 00256 ipv6_route_t *ipv6_route_choose_next_hop(const uint8_t *dest, int8_t interface_id, ipv6_route_predicate_fn_t *predicate); 00257 00258 void ipv6_route_table_change_next_hop_for_info(int8_t interface_id, const uint8_t *next_hop, ipv6_route_src_t source, void *info); 00259 void ipv6_route_table_remove_interface(int8_t interface_id); 00260 void ipv6_route_table_modify_router_metric(int8_t interface_id, const uint8_t *addr, ipv6_route_src_t source, uint8_t keep, uint8_t toggle); 00261 void ipv6_route_table_remove_info(int8_t interface_id, ipv6_route_src_t source, void *info); 00262 void ipv6_route_table_set_predicate_fn(ipv6_route_src_t src, ipv6_route_predicate_fn_t *fn); 00263 void ipv6_route_table_set_next_hop_fn(ipv6_route_src_t src, ipv6_route_next_hop_fn_t *fn); 00264 void ipv6_route_table_ttl_update(uint16_t seconds); 00265 void ipv6_route_table_print(route_print_fn_t *print_fn); 00266 void ipv6_route_table_set_max_entries(int8_t interface_id, ipv6_route_src_t source, uint8_t max_entries); 00267 bool ipv6_route_table_source_was_invalidated(ipv6_route_src_t src); 00268 void ipv6_route_table_source_invalidated_reset(void); 00269 00270 #endif /* IPV6_ROUTING_TABLE_H_ */
Generated on Tue Jul 12 2022 13:54:25 by
