Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ipv6_routing_table.h Source File

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_ */