takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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