Knight KE / Mbed OS Game_Master
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-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  * 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/address.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 route */
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_BBR,
00086     ROUTE_REDIRECT,     /* Only occurs in destination cache */
00087     ROUTE_MAX,
00088 } ipv6_route_src_t;
00089 
00090 struct buffer;
00091 
00092 typedef struct ipv6_neighbour {
00093     uint8_t                         ip_address[16];             /*!< neighbour IP address */
00094     bool                            is_router: 1;
00095     bool                            from_redirect: 1;
00096     uint8_t                         retrans_count;
00097     ip_neighbour_cache_state_t      state;
00098     ip_neighbour_cache_type_t       type;
00099     addrtype_t                      ll_type;
00100     uint32_t                        timer;                      /* 100ms ticks */
00101     uint32_t                        lifetime;                   /* seconds */
00102     ns_list_link_t                  link;                       /*!< List link */
00103     NS_LIST_HEAD_INCOMPLETE(struct buffer) queue;
00104     uint8_t                         ll_address[];
00105 } ipv6_neighbour_t;
00106 
00107 /* Neighbour Cache entries also store EUI-64 after ll_address if "recv_addr_reg"
00108  * is set for the cache. This is ADDR_EUI64_ZERO if unknown.
00109  */
00110 #define ipv6_neighbour_eui64(ncache, entry) ((entry)->ll_address + (ncache)->max_ll_len)
00111 
00112 typedef struct ipv6_route_info_cache {
00113     uint16_t                                metric; // interface metric
00114     uint8_t                                 sources[ROUTE_MAX];
00115 } ipv6_route_interface_info_t;
00116 
00117 typedef struct ipv6_neighbour_cache {
00118     bool                                    send_addr_reg : 1;
00119     bool                                    recv_addr_reg : 1;
00120     bool                                    send_nud_probes : 1;
00121     bool                                    recv_ns_aro : 1;
00122     bool                                    recv_na_aro : 1;
00123     int8_t                                  interface_id;
00124     uint8_t                                 max_ll_len;
00125     uint8_t                                 gc_timer;
00126     uint16_t                                link_mtu;
00127     uint32_t                                retrans_timer;
00128     uint32_t                                reachable_time;
00129     // Interface specific information for route
00130     ipv6_route_interface_info_t             route_if_info;
00131     //uint8_t                                   num_entries;
00132     NS_LIST_HEAD (ipv6_neighbour_t, link)    list;
00133 } ipv6_neighbour_cache_t;
00134 
00135 /* Macros for formatting ipv6 addresses into strings for route printing. */
00136 /* Initialize a string buffer for the ipv6 address */
00137 #define ROUTE_PRINT_ADDR_STR_BUFFER_INIT(str) char str[41] = "<null>"
00138 /* Format and store ipv6 'addr' into 'str', and evaluate 'str' */
00139 #define ROUTE_PRINT_ADDR_STR_FORMAT(str, addr) (ip6tos(addr, str), str)
00140 
00141 /* Callback type for route print */
00142 typedef void (route_print_fn_t)(const char *fmt, ...);
00143 
00144 extern void ipv6_neighbour_cache_init(ipv6_neighbour_cache_t *cache, int8_t interface_id);
00145 extern void ipv6_neighbour_cache_flush(ipv6_neighbour_cache_t *cache);
00146 extern ipv6_neighbour_t *ipv6_neighbour_update(ipv6_neighbour_cache_t *cache, const uint8_t *address, bool solicited);
00147 extern void ipv6_neighbour_set_state(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, ip_neighbour_cache_state_t state);
00148 extern ipv6_neighbour_t *ipv6_neighbour_used(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry);
00149 extern ipv6_neighbour_t *ipv6_neighbour_lookup(ipv6_neighbour_cache_t *cache, const uint8_t *address);
00150 extern ipv6_neighbour_t *ipv6_neighbour_lookup_by_interface_id(int8_t interface_id, const uint8_t *address);
00151 extern ipv6_neighbour_t *ipv6_neighbour_lookup_or_create(ipv6_neighbour_cache_t *cache, const uint8_t *address);
00152 extern ipv6_neighbour_t *ipv6_neighbour_lookup_or_create_by_interface_id(int8_t interface_id, const uint8_t *address);
00153 extern void ipv6_neighbour_entry_remove(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry);
00154 extern bool ipv6_neighbour_is_probably_reachable(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *n);
00155 extern bool ipv6_neighbour_addr_is_probably_reachable(ipv6_neighbour_cache_t *cache, const uint8_t *address);
00156 extern bool ipv6_neighbour_ll_addr_match(const ipv6_neighbour_t *entry, addrtype_t ll_type, const uint8_t *ll_address);
00157 extern void ipv6_neighbour_invalidate_ll_addr(ipv6_neighbour_cache_t *cache, addrtype_t ll_type, const uint8_t *ll_address);
00158 extern void ipv6_neighbour_delete_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64);
00159 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*/);
00160 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);
00161 extern void ipv6_neighbour_reachability_confirmation(const uint8_t ip_address[__static 16], int8_t interface_id);
00162 extern void ipv6_neighbour_reachability_problem(const uint8_t ip_address[__static 16], int8_t interface_id);
00163 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);
00164 extern void ipv6_neighbour_cache_fast_timer(ipv6_neighbour_cache_t *cache, uint16_t ticks);
00165 extern void ipv6_neighbour_cache_slow_timer(ipv6_neighbour_cache_t *cache, uint8_t seconds);
00166 extern void ipv6_neighbour_cache_print(const ipv6_neighbour_cache_t *cache, route_print_fn_t *print_fn);
00167 extern void ipv6_router_gone(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry);
00168 
00169 extern int8_t ipv6_neighbour_set_current_max_cache(uint16_t max_cache);
00170 
00171 /* Backwards compatibility with test app */
00172 #define ROUTE_RPL_UP ROUTE_RPL_DIO
00173 #define ROUTE_RPL_DOWN ROUTE_RPL_DAO
00174 
00175 typedef struct ipv6_route_info {
00176     ipv6_route_src_t                source;
00177     uint8_t                         source_id;
00178     int8_t                          interface_id;
00179     uint16_t                        pmtu;
00180     void                            *info;              // pointer to route provider's info
00181     uint8_t                         next_hop_addr[16];
00182 } ipv6_route_info_t;
00183 
00184 typedef struct ipv6_destination {
00185     /* Destination/path information */
00186     uint8_t                         destination[16];
00187 #ifdef HAVE_IPV6_ND
00188     uint8_t                         redirect_addr[16];
00189     bool                            redirected;         // we have a redirect in force
00190 #endif
00191     int8_t                          interface_id;       // fixed if link-local destination, else variable and gets set from redirect interface and/or last_neighbour interface
00192     uint16_t                        refcount;
00193     uint16_t                        lifetime;           // Life in GC calls, so 20s units
00194 #ifndef NO_IPV6_PMTUD
00195     uint16_t                        pmtu;               // note this may be less than 1280 - upper layers may choose to send smaller based on this
00196     uint16_t                        pmtu_lifetime;      // seconds
00197 #endif
00198 #ifndef NO_IP_FRAGMENT_TX
00199     uint32_t                        fragment_id;
00200 #endif
00201     ipv6_neighbour_t                *last_neighbour;    // last neighbour used (only for reachability confirmation)
00202     ns_list_link_t                  link;
00203 } ipv6_destination_t;
00204 
00205 #ifndef NO_IPV6_PMTUD
00206 #define ipv6_destination_pmtu(d) ((d)->pmtu)
00207 #else
00208 #define ipv6_destination_pmtu(d) IPV6_MIN_LINK_MTU
00209 #endif
00210 
00211 void ipv6_destination_cache_print(route_print_fn_t *print_fn);
00212 ipv6_destination_t *ipv6_destination_lookup_or_create(const uint8_t *address, int8_t interface_id);
00213 ipv6_destination_t *ipv6_destination_lookup_or_create_with_route(const uint8_t *address, int8_t interface_id, ipv6_route_info_t *route_out);
00214 void ipv6_destination_cache_timer(uint8_t ticks);
00215 #ifdef HAVE_IPV6_ND
00216 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);
00217 #endif
00218 /* Combined Routing Table (RFC 4191) and Prefix List (RFC 4861) */
00219 /* On-link prefixes have the on_link flag set and next_hop is unset */
00220 typedef struct ipv6_route {
00221     uint8_t             prefix_len;
00222     bool                on_link: 1;
00223     bool                search_skip: 1;
00224     bool                probe: 1;
00225     uint8_t             metric;             // 0x40 = RFC 4191 pref high, 0x80 = default, 0xC0 = RFC 4191 pref low
00226     ipv6_route_info_t   info;
00227     uint32_t            lifetime;           // (seconds); 0xFFFFFFFF means permanent
00228     uint16_t            probe_timer;
00229     ns_list_link_t      link;
00230     uint8_t             prefix[];           // variable length
00231 } ipv6_route_t;
00232 
00233 /* Callback type for route predicate */
00234 typedef bool ipv6_route_predicate_fn_t(const ipv6_route_info_t *route, bool valid);
00235 
00236 /* Callbacks for route providers that dynamically compute next hop */
00237 typedef bool ipv6_route_next_hop_fn_t(const uint8_t *dest, ipv6_route_info_t *route_info);
00238 
00239 uint8_t ipv6_route_pref_to_metric(int_fast8_t pref);
00240 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);
00241 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);
00242 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);
00243 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);
00244 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);
00245 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);
00246 ipv6_route_t *ipv6_route_choose_next_hop(const uint8_t *dest, int8_t interface_id, ipv6_route_predicate_fn_t *predicate);
00247 
00248 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);
00249 void ipv6_route_table_remove_interface(int8_t interface_id);
00250 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);
00251 void ipv6_route_table_remove_info(int8_t interface_id, ipv6_route_src_t source, void *info);
00252 void ipv6_route_table_set_predicate_fn(ipv6_route_src_t src, ipv6_route_predicate_fn_t *fn);
00253 void ipv6_route_table_set_next_hop_fn(ipv6_route_src_t src, ipv6_route_next_hop_fn_t *fn);
00254 void ipv6_route_table_ttl_update(uint16_t seconds);
00255 void ipv6_route_table_print(route_print_fn_t *print_fn);
00256 void ipv6_route_table_set_max_entries(int8_t interface_id, ipv6_route_src_t source, uint8_t max_entries);
00257 bool ipv6_route_table_source_was_invalidated(ipv6_route_src_t src);
00258 void ipv6_route_table_source_invalidated_reset(void);
00259 
00260 #endif /* IPV6_ROUTING_TABLE_H_ */