1 /* 2 * Copyright (c) 2021-22, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * @brief 32 * This file defines the OpenThread Border Routing Manager API. 33 */ 34 35 #ifndef OPENTHREAD_BORDER_ROUTING_H_ 36 #define OPENTHREAD_BORDER_ROUTING_H_ 37 38 #include <openthread/error.h> 39 #include <openthread/ip6.h> 40 #include <openthread/netdata.h> 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 /** 47 * @addtogroup api-border-routing 48 * 49 * @brief 50 * This module includes definitions related to Border Routing Manager. 51 * 52 * 53 * @{ 54 * 55 * All the functions in this module require `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE` to be enabled. 56 * 57 * Border Routing Manager handles bi-directional routing between Thread network and adjacent infrastructure link (AIL). 58 * 59 * It emits ICMRv6 ND Router Advertisement (RA) messages on AIL to advertise on-link and route prefixes. It also 60 * processes received RA messages from infrastructure and mirrors the discovered prefixes on the Thread Network Data to 61 * ensure devices on Thread mesh can reach AIL through the Border Router. 62 * 63 * Routing Manager manages the Off-Mesh Routable (OMR) prefix on the Thread Network data which configures Thread 64 * devices with a suitable Off-Mesh Routable IPv6 address. It announces the reachability of this prefix on AIL by 65 * including it in the emitted RA messages as an IPv6 Route Information Option (RIO). 66 * 67 * Routing Manager also monitors and adds on-link prefix on the infrastructure network. If a router on AIL is already 68 * providing RA messages containing an IPv6 Prefix Information Option (PIO) that enables IPv6 devices on the link to 69 * self-configure their own routable unicast IPv6 address, this address can be used by Thread devices to reach AIL. If 70 * Border Router finds no such RA message on AIL, it generates a ULA on-link prefix which it then advertises on AIL in 71 * the emitted RA messages. 72 * 73 */ 74 75 /** 76 * Represents an iterator to iterate through the Border Router's discovered prefix table. 77 * 78 * The fields in this type are opaque (intended for use by OpenThread core only) and therefore should not be 79 * accessed or used by caller. 80 * 81 * Before using an iterator, it MUST be initialized using `otBorderRoutingPrefixTableInitIterator()`. 82 * 83 */ 84 typedef struct otBorderRoutingPrefixTableIterator 85 { 86 const void *mPtr1; 87 const void *mPtr2; 88 uint32_t mData32; 89 } otBorderRoutingPrefixTableIterator; 90 91 /** 92 * Represents an entry from the discovered prefix table. 93 * 94 * The entries in the discovered table track the Prefix/Route Info Options in the received Router Advertisement messages 95 * from other routers on infrastructure link. 96 * 97 */ 98 typedef struct otBorderRoutingPrefixTableEntry 99 { 100 otIp6Address mRouterAddress; ///< IPv6 address of the router. 101 otIp6Prefix mPrefix; ///< The discovered IPv6 prefix. 102 bool mIsOnLink; ///< Indicates whether the prefix is on-link or route prefix. 103 uint32_t mMsecSinceLastUpdate; ///< Milliseconds since last update of this prefix. 104 uint32_t mValidLifetime; ///< Valid lifetime of the prefix (in seconds). 105 otRoutePreference mRoutePreference; ///< Route preference when `mIsOnlink` is false. 106 uint32_t mPreferredLifetime; ///< Preferred lifetime of the on-link prefix when `mIsOnLink` is true. 107 } otBorderRoutingPrefixTableEntry; 108 109 /** 110 * Represents the state of Border Routing Manager. 111 * 112 */ 113 typedef enum 114 { 115 OT_BORDER_ROUTING_STATE_UNINITIALIZED, ///< Routing Manager is uninitialized. 116 OT_BORDER_ROUTING_STATE_DISABLED, ///< Routing Manager is initialized but disabled. 117 OT_BORDER_ROUTING_STATE_STOPPED, ///< Routing Manager in initialized and enabled but currently stopped. 118 OT_BORDER_ROUTING_STATE_RUNNING, ///< Routing Manager is initialized, enabled, and running. 119 } otBorderRoutingState; 120 121 /** 122 * This enumeration represents the state of DHCPv6 Prefix Delegation State. 123 * 124 */ 125 typedef enum 126 { 127 OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED, ///< DHCPv6 PD is disabled on the border router. 128 OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED, ///< DHCPv6 PD in enabled but won't try to request and publish a prefix. 129 OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING, ///< DHCPv6 PD is enabled and will try to request and publish a prefix. 130 } otBorderRoutingDhcp6PdState; 131 132 /** 133 * Initializes the Border Routing Manager on given infrastructure interface. 134 * 135 * @note This method MUST be called before any other otBorderRouting* APIs. 136 * @note This method can be re-called to change the infrastructure interface, but the Border Routing Manager should be 137 * disabled first, and re-enabled after. 138 * 139 * @param[in] aInstance A pointer to an OpenThread instance. 140 * @param[in] aInfraIfIndex The infrastructure interface index. 141 * @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure 142 * interface is running. 143 * 144 * @retval OT_ERROR_NONE Successfully started the Border Routing Manager on given infrastructure. 145 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is in a state other than disabled or uninitialized. 146 * @retval OT_ERROR_INVALID_ARGS The index of the infrastructure interface is not valid. 147 * @retval OT_ERROR_FAILED Internal failure. Usually due to failure in generating random prefixes. 148 * 149 * @sa otPlatInfraIfStateChanged. 150 * @sa otBorderRoutingSetEnabled. 151 * 152 */ 153 otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning); 154 155 /** 156 * Enables or disables the Border Routing Manager. 157 * 158 * @note The Border Routing Manager is disabled by default. 159 * 160 * @param[in] aInstance A pointer to an OpenThread instance. 161 * @param[in] aEnabled A boolean to enable/disable the routing manager. 162 * 163 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 164 * @retval OT_ERROR_NONE Successfully enabled/disabled the Border Routing Manager. 165 * 166 */ 167 otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled); 168 169 /** 170 * Gets the current state of Border Routing Manager. 171 * 172 * @param[in] aInstance A pointer to an OpenThread instance. 173 * 174 * @returns The current state of Border Routing Manager. 175 * 176 */ 177 otBorderRoutingState otBorderRoutingGetState(otInstance *aInstance); 178 179 /** 180 * Gets the current preference used when advertising Route Info Options (RIO) in Router Advertisement 181 * messages sent over the infrastructure link. 182 * 183 * The RIO preference is determined as follows: 184 * 185 * - If explicitly set by user by calling `otBorderRoutingSetRouteInfoOptionPreference()`, the given preference is 186 * used. 187 * - Otherwise, it is determined based on device's current role: Medium preference when in router/leader role and 188 * low preference when in child role. 189 * 190 * @returns The current Route Info Option preference. 191 * 192 */ 193 otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInstance); 194 195 /** 196 * Explicitly sets the preference to use when advertising Route Info Options (RIO) in Router 197 * Advertisement messages sent over the infrastructure link. 198 * 199 * After a call to this function, BR will use the given preference for all its advertised RIOs. The preference can be 200 * cleared by calling `otBorderRoutingClearRouteInfoOptionPreference()`. 201 * 202 * @param[in] aInstance A pointer to an OpenThread instance. 203 * @param[in] aPreference The route preference to use. 204 * 205 */ 206 void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRoutePreference aPreference); 207 208 /** 209 * Clears a previously set preference value for advertised Route Info Options. 210 * 211 * After a call to this function, BR will use device's role to determine the RIO preference: Medium preference when 212 * in router/leader role and low preference when in child role. 213 * 214 * @param[in] aInstance A pointer to an OpenThread instance. 215 * 216 */ 217 void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance); 218 219 /** 220 * Gets the current preference used for published routes in Network Data. 221 * 222 * The preference is determined as follows: 223 * 224 * - If explicitly set by user by calling `otBorderRoutingSetRoutePreference()`, the given preference is used. 225 * - Otherwise, it is determined automatically by `RoutingManager` based on the device's role and link quality. 226 * 227 * @param[in] aInstance A pointer to an OpenThread instance. 228 * 229 * @returns The current published route preference. 230 * 231 */ 232 otRoutePreference otBorderRoutingGetRoutePreference(otInstance *aInstance); 233 234 /** 235 * Explicitly sets the preference of published routes in Network Data. 236 * 237 * After a call to this function, BR will use the given preference. The preference can be cleared by calling 238 * `otBorderRoutingClearRoutePreference()`. 239 * 240 * @param[in] aInstance A pointer to an OpenThread instance. 241 * @param[in] aPreference The route preference to use. 242 * 243 */ 244 void otBorderRoutingSetRoutePreference(otInstance *aInstance, otRoutePreference aPreference); 245 246 /** 247 * Clears a previously set preference value for published routes in Network Data. 248 * 249 * After a call to this function, BR will determine the preference automatically based on the device's role and 250 * link quality (to the parent when acting as end-device). 251 * 252 * @param[in] aInstance A pointer to an OpenThread instance. 253 * 254 */ 255 void otBorderRoutingClearRoutePreference(otInstance *aInstance); 256 257 /** 258 * Gets the local Off-Mesh-Routable (OMR) Prefix, for example `fdfc:1ff5:1512:5622::/64`. 259 * 260 * An OMR Prefix is a randomly generated 64-bit prefix that's published in the 261 * Thread network if there isn't already an OMR prefix. This prefix can be reached 262 * from the local Wi-Fi or Ethernet network. 263 * 264 * Note: When DHCPv6 PD is enabled, the border router may publish the prefix from 265 * DHCPv6 PD. 266 * 267 * @param[in] aInstance A pointer to an OpenThread instance. 268 * @param[out] aPrefix A pointer to where the prefix will be output to. 269 * 270 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 271 * @retval OT_ERROR_NONE Successfully retrieved the OMR prefix. 272 * 273 * @sa otBorderRoutingGetPdOmrPrefix 274 * 275 */ 276 otError otBorderRoutingGetOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix); 277 278 /** 279 * Gets the DHCPv6 Prefix Delegation (PD) provided off-mesh-routable (OMR) prefix. 280 * 281 * Only mPrefix, mValidLifetime and mPreferredLifetime fields are used in the returned prefix info. 282 * 283 * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled. 284 * 285 * @param[in] aInstance A pointer to an OpenThread instance. 286 * @param[out] aPrefixInfo A pointer to where the prefix info will be output to. 287 * 288 * @retval OT_ERROR_NONE Successfully retrieved the OMR prefix. 289 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 290 * @retval OT_ERROR_NOT_FOUND There are no valid PD prefix on this BR. 291 * 292 * @sa otBorderRoutingGetOmrPrefix 293 * @sa otPlatBorderRoutingProcessIcmp6Ra 294 * 295 */ 296 otError otBorderRoutingGetPdOmrPrefix(otInstance *aInstance, otBorderRoutingPrefixTableEntry *aPrefixInfo); 297 298 /** 299 * Gets the currently favored Off-Mesh-Routable (OMR) Prefix. 300 * 301 * The favored OMR prefix can be discovered from Network Data or can be this device's local OMR prefix. 302 * 303 * @param[in] aInstance A pointer to an OpenThread instance. 304 * @param[out] aPrefix A pointer to output the favored OMR prefix. 305 * @param[out] aPreference A pointer to output the preference associated the favored prefix. 306 * 307 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not running yet. 308 * @retval OT_ERROR_NONE Successfully retrieved the favored OMR prefix. 309 * 310 */ 311 otError otBorderRoutingGetFavoredOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix, otRoutePreference *aPreference); 312 313 /** 314 * Gets the local On-Link Prefix for the adjacent infrastructure link. 315 * 316 * The local On-Link Prefix is a 64-bit prefix that's advertised on the infrastructure link if there isn't already a 317 * usable on-link prefix being advertised on the link. 318 * 319 * @param[in] aInstance A pointer to an OpenThread instance. 320 * @param[out] aPrefix A pointer to where the prefix will be output to. 321 * 322 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 323 * @retval OT_ERROR_NONE Successfully retrieved the local on-link prefix. 324 * 325 */ 326 otError otBorderRoutingGetOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPrefix); 327 328 /** 329 * Gets the currently favored On-Link Prefix. 330 * 331 * The favored prefix is either a discovered on-link prefix on the infrastructure link or the local on-link prefix. 332 * 333 * @param[in] aInstance A pointer to an OpenThread instance. 334 * @param[out] aPrefix A pointer to where the prefix will be output to. 335 * 336 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 337 * @retval OT_ERROR_NONE Successfully retrieved the favored on-link prefix. 338 * 339 */ 340 otError otBorderRoutingGetFavoredOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPrefix); 341 342 /** 343 * Gets the local NAT64 Prefix of the Border Router. 344 * 345 * NAT64 Prefix might not be advertised in the Thread network. 346 * 347 * `OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE` must be enabled. 348 * 349 * @param[in] aInstance A pointer to an OpenThread instance. 350 * @param[out] aPrefix A pointer to where the prefix will be output to. 351 * 352 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 353 * @retval OT_ERROR_NONE Successfully retrieved the NAT64 prefix. 354 * 355 */ 356 otError otBorderRoutingGetNat64Prefix(otInstance *aInstance, otIp6Prefix *aPrefix); 357 358 /** 359 * Gets the currently favored NAT64 prefix. 360 * 361 * The favored NAT64 prefix can be discovered from infrastructure link or can be this device's local NAT64 prefix. 362 * 363 * @param[in] aInstance A pointer to an OpenThread instance. 364 * @param[out] aPrefix A pointer to output the favored NAT64 prefix. 365 * @param[out] aPreference A pointer to output the preference associated the favored prefix. 366 * 367 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 368 * @retval OT_ERROR_NONE Successfully retrieved the favored NAT64 prefix. 369 * 370 */ 371 otError otBorderRoutingGetFavoredNat64Prefix(otInstance *aInstance, 372 otIp6Prefix *aPrefix, 373 otRoutePreference *aPreference); 374 375 /** 376 * Initializes an `otBorderRoutingPrefixTableIterator`. 377 * 378 * An iterator MUST be initialized before it is used. 379 * 380 * An iterator can be initialized again to restart from the beginning of the table. 381 * 382 * When iterating over entries in the table, to ensure the update times `mMsecSinceLastUpdate` of entries are 383 * consistent, they are given relative to the time the iterator was initialized. 384 * 385 * @param[in] aInstance The OpenThread instance. 386 * @param[out] aIterator A pointer to the iterator to initialize. 387 * 388 */ 389 void otBorderRoutingPrefixTableInitIterator(otInstance *aInstance, otBorderRoutingPrefixTableIterator *aIterator); 390 391 /** 392 * Iterates over the entries in the Border Router's discovered prefix table. 393 * 394 * @param[in] aInstance The OpenThread instance. 395 * @param[in,out] aIterator A pointer to the iterator. 396 * @param[out] aEntry A pointer to the entry to populate. 397 * 398 * @retval OT_ERROR_NONE Iterated to the next entry, @p aEntry and @p aIterator are updated. 399 * @retval OT_ERROR_NOT_FOUND No more entries in the table. 400 * 401 */ 402 otError otBorderRoutingGetNextPrefixTableEntry(otInstance *aInstance, 403 otBorderRoutingPrefixTableIterator *aIterator, 404 otBorderRoutingPrefixTableEntry *aEntry); 405 406 /** 407 * Enables / Disables DHCPv6 Prefix Delegation. 408 * 409 * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled. 410 * 411 * @param[in] aInstance A pointer to an OpenThread instance. 412 * @param[in] aEnabled Whether to accept platform generated RA messages. 413 * 414 */ 415 void otBorderRoutingDhcp6PdSetEnabled(otInstance *aInstance, bool aEnabled); 416 417 /** 418 * @} 419 * 420 */ 421 422 #ifdef __cplusplus 423 } // extern "C" 424 #endif 425 426 #endif // OPENTHREAD_BORDER_ROUTING_H_ 427