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 a discovered router on the infrastructure link. 93 * 94 */ 95 typedef struct otBorderRoutingRouterEntry 96 { 97 otIp6Address mAddress; ///< IPv6 address of the router. 98 bool mManagedAddressConfigFlag : 1; ///< The router's Managed Address Config flag (`M` flag). 99 bool mOtherConfigFlag : 1; ///< The router's Other Config flag (`O` flag). 100 bool mStubRouterFlag : 1; ///< The router's Stub Router flag. 101 } otBorderRoutingRouterEntry; 102 103 /** 104 * Represents an entry from the discovered prefix table. 105 * 106 * The entries in the discovered table track the Prefix/Route Info Options in the received Router Advertisement messages 107 * from other routers on the infrastructure link. 108 * 109 */ 110 typedef struct otBorderRoutingPrefixTableEntry 111 { 112 otBorderRoutingRouterEntry mRouter; ///< Information about the router advertising this prefix. 113 otIp6Prefix mPrefix; ///< The discovered IPv6 prefix. 114 bool mIsOnLink; ///< Indicates whether the prefix is on-link or route prefix. 115 uint32_t mMsecSinceLastUpdate; ///< Milliseconds since last update of this prefix. 116 uint32_t mValidLifetime; ///< Valid lifetime of the prefix (in seconds). 117 otRoutePreference mRoutePreference; ///< Route preference when `mIsOnlink` is false. 118 uint32_t mPreferredLifetime; ///< Preferred lifetime of the on-link prefix when `mIsOnLink`. 119 } otBorderRoutingPrefixTableEntry; 120 121 /** 122 * Represents a group of data of platform-generated RA messages processed. 123 * 124 */ 125 typedef struct otPdProcessedRaInfo 126 { 127 uint32_t mNumPlatformRaReceived; ///< The number of platform generated RA handled by ProcessPlatformGeneratedRa. 128 uint32_t mNumPlatformPioProcessed; ///< The number of PIO processed for adding OMR prefixes. 129 uint32_t mLastPlatformRaMsec; ///< The timestamp of last processed RA message. 130 } otPdProcessedRaInfo; 131 132 /** 133 * Represents the state of Border Routing Manager. 134 * 135 */ 136 typedef enum 137 { 138 OT_BORDER_ROUTING_STATE_UNINITIALIZED, ///< Routing Manager is uninitialized. 139 OT_BORDER_ROUTING_STATE_DISABLED, ///< Routing Manager is initialized but disabled. 140 OT_BORDER_ROUTING_STATE_STOPPED, ///< Routing Manager in initialized and enabled but currently stopped. 141 OT_BORDER_ROUTING_STATE_RUNNING, ///< Routing Manager is initialized, enabled, and running. 142 } otBorderRoutingState; 143 144 /** 145 * This enumeration represents the state of DHCPv6 Prefix Delegation State. 146 * 147 */ 148 typedef enum 149 { 150 OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED, ///< DHCPv6 PD is disabled on the border router. 151 OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED, ///< DHCPv6 PD in enabled but won't try to request and publish a prefix. 152 OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING, ///< DHCPv6 PD is enabled and will try to request and publish a prefix. 153 } otBorderRoutingDhcp6PdState; 154 155 /** 156 * Initializes the Border Routing Manager on given infrastructure interface. 157 * 158 * @note This method MUST be called before any other otBorderRouting* APIs. 159 * @note This method can be re-called to change the infrastructure interface, but the Border Routing Manager should be 160 * disabled first, and re-enabled after. 161 * 162 * @param[in] aInstance A pointer to an OpenThread instance. 163 * @param[in] aInfraIfIndex The infrastructure interface index. 164 * @param[in] aInfraIfIsRunning A boolean that indicates whether the infrastructure 165 * interface is running. 166 * 167 * @retval OT_ERROR_NONE Successfully started the Border Routing Manager on given infrastructure. 168 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is in a state other than disabled or uninitialized. 169 * @retval OT_ERROR_INVALID_ARGS The index of the infrastructure interface is not valid. 170 * @retval OT_ERROR_FAILED Internal failure. Usually due to failure in generating random prefixes. 171 * 172 * @sa otPlatInfraIfStateChanged. 173 * @sa otBorderRoutingSetEnabled. 174 * 175 */ 176 otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning); 177 178 /** 179 * Enables or disables the Border Routing Manager. 180 * 181 * @note The Border Routing Manager is disabled by default. 182 * 183 * @param[in] aInstance A pointer to an OpenThread instance. 184 * @param[in] aEnabled A boolean to enable/disable the routing manager. 185 * 186 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 187 * @retval OT_ERROR_NONE Successfully enabled/disabled the Border Routing Manager. 188 * 189 */ 190 otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled); 191 192 /** 193 * Gets the current state of Border Routing Manager. 194 * 195 * @param[in] aInstance A pointer to an OpenThread instance. 196 * 197 * @returns The current state of Border Routing Manager. 198 * 199 */ 200 otBorderRoutingState otBorderRoutingGetState(otInstance *aInstance); 201 202 /** 203 * Gets the current preference used when advertising Route Info Options (RIO) in Router Advertisement 204 * messages sent over the infrastructure link. 205 * 206 * The RIO preference is determined as follows: 207 * 208 * - If explicitly set by user by calling `otBorderRoutingSetRouteInfoOptionPreference()`, the given preference is 209 * used. 210 * - Otherwise, it is determined based on device's current role: Medium preference when in router/leader role and 211 * low preference when in child role. 212 * 213 * @returns The current Route Info Option preference. 214 * 215 */ 216 otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInstance); 217 218 /** 219 * Explicitly sets the preference to use when advertising Route Info Options (RIO) in Router 220 * Advertisement messages sent over the infrastructure link. 221 * 222 * After a call to this function, BR will use the given preference for all its advertised RIOs. The preference can be 223 * cleared by calling `otBorderRoutingClearRouteInfoOptionPreference()`. 224 * 225 * @param[in] aInstance A pointer to an OpenThread instance. 226 * @param[in] aPreference The route preference to use. 227 * 228 */ 229 void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRoutePreference aPreference); 230 231 /** 232 * Clears a previously set preference value for advertised Route Info Options. 233 * 234 * After a call to this function, BR will use device's role to determine the RIO preference: Medium preference when 235 * in router/leader role and low preference when in child role. 236 * 237 * @param[in] aInstance A pointer to an OpenThread instance. 238 * 239 */ 240 void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance); 241 242 /** 243 * Gets the current preference used for published routes in Network Data. 244 * 245 * The preference is determined as follows: 246 * 247 * - If explicitly set by user by calling `otBorderRoutingSetRoutePreference()`, the given preference is used. 248 * - Otherwise, it is determined automatically by `RoutingManager` based on the device's role and link quality. 249 * 250 * @param[in] aInstance A pointer to an OpenThread instance. 251 * 252 * @returns The current published route preference. 253 * 254 */ 255 otRoutePreference otBorderRoutingGetRoutePreference(otInstance *aInstance); 256 257 /** 258 * Explicitly sets the preference of published routes in Network Data. 259 * 260 * After a call to this function, BR will use the given preference. The preference can be cleared by calling 261 * `otBorderRoutingClearRoutePreference()`. 262 * 263 * @param[in] aInstance A pointer to an OpenThread instance. 264 * @param[in] aPreference The route preference to use. 265 * 266 */ 267 void otBorderRoutingSetRoutePreference(otInstance *aInstance, otRoutePreference aPreference); 268 269 /** 270 * Clears a previously set preference value for published routes in Network Data. 271 * 272 * After a call to this function, BR will determine the preference automatically based on the device's role and 273 * link quality (to the parent when acting as end-device). 274 * 275 * @param[in] aInstance A pointer to an OpenThread instance. 276 * 277 */ 278 void otBorderRoutingClearRoutePreference(otInstance *aInstance); 279 280 /** 281 * Gets the local Off-Mesh-Routable (OMR) Prefix, for example `fdfc:1ff5:1512:5622::/64`. 282 * 283 * An OMR Prefix is a randomly generated 64-bit prefix that's published in the 284 * Thread network if there isn't already an OMR prefix. This prefix can be reached 285 * from the local Wi-Fi or Ethernet network. 286 * 287 * Note: When DHCPv6 PD is enabled, the border router may publish the prefix from 288 * DHCPv6 PD. 289 * 290 * @param[in] aInstance A pointer to an OpenThread instance. 291 * @param[out] aPrefix A pointer to where the prefix will be output to. 292 * 293 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 294 * @retval OT_ERROR_NONE Successfully retrieved the OMR prefix. 295 * 296 * @sa otBorderRoutingGetPdOmrPrefix 297 * 298 */ 299 otError otBorderRoutingGetOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix); 300 301 /** 302 * Gets the DHCPv6 Prefix Delegation (PD) provided off-mesh-routable (OMR) prefix. 303 * 304 * Only mPrefix, mValidLifetime and mPreferredLifetime fields are used in the returned prefix info. 305 * 306 * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled. 307 * 308 * @param[in] aInstance A pointer to an OpenThread instance. 309 * @param[out] aPrefixInfo A pointer to where the prefix info will be output to. 310 * 311 * @retval OT_ERROR_NONE Successfully retrieved the OMR prefix. 312 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 313 * @retval OT_ERROR_NOT_FOUND There are no valid PD prefix on this BR. 314 * 315 * @sa otBorderRoutingGetOmrPrefix 316 * @sa otPlatBorderRoutingProcessIcmp6Ra 317 * 318 */ 319 otError otBorderRoutingGetPdOmrPrefix(otInstance *aInstance, otBorderRoutingPrefixTableEntry *aPrefixInfo); 320 321 /** 322 * Gets the data of platform generated RA message processed.. 323 * 324 * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled. 325 * 326 * @param[in] aInstance A pointer to an OpenThread instance. 327 * @param[out] aPrefixInfo A pointer to where the prefix info will be output to. 328 * 329 * @retval OT_ERROR_NONE Successfully retrieved the Info. 330 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 331 * @retval OT_ERROR_NOT_FOUND There are no valid Info on this BR. 332 * 333 */ 334 otError otBorderRoutingGetPdProcessedRaInfo(otInstance *aInstance, otPdProcessedRaInfo *aPdProcessedRaInfo); 335 336 /** 337 * Gets the currently favored Off-Mesh-Routable (OMR) Prefix. 338 * 339 * The favored OMR prefix can be discovered from Network Data or can be this device's local OMR prefix. 340 * 341 * @param[in] aInstance A pointer to an OpenThread instance. 342 * @param[out] aPrefix A pointer to output the favored OMR prefix. 343 * @param[out] aPreference A pointer to output the preference associated the favored prefix. 344 * 345 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not running yet. 346 * @retval OT_ERROR_NONE Successfully retrieved the favored OMR prefix. 347 * 348 */ 349 otError otBorderRoutingGetFavoredOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix, otRoutePreference *aPreference); 350 351 /** 352 * Gets the local On-Link Prefix for the adjacent infrastructure link. 353 * 354 * The local On-Link Prefix is a 64-bit prefix that's advertised on the infrastructure link if there isn't already a 355 * usable on-link prefix being advertised on the link. 356 * 357 * @param[in] aInstance A pointer to an OpenThread instance. 358 * @param[out] aPrefix A pointer to where the prefix will be output to. 359 * 360 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 361 * @retval OT_ERROR_NONE Successfully retrieved the local on-link prefix. 362 * 363 */ 364 otError otBorderRoutingGetOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPrefix); 365 366 /** 367 * Gets the currently favored On-Link Prefix. 368 * 369 * The favored prefix is either a discovered on-link prefix on the infrastructure link or the local on-link prefix. 370 * 371 * @param[in] aInstance A pointer to an OpenThread instance. 372 * @param[out] aPrefix A pointer to where the prefix will be output to. 373 * 374 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 375 * @retval OT_ERROR_NONE Successfully retrieved the favored on-link prefix. 376 * 377 */ 378 otError otBorderRoutingGetFavoredOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPrefix); 379 380 /** 381 * Gets the local NAT64 Prefix of the Border Router. 382 * 383 * NAT64 Prefix might not be advertised in the Thread network. 384 * 385 * `OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE` must be enabled. 386 * 387 * @param[in] aInstance A pointer to an OpenThread instance. 388 * @param[out] aPrefix A pointer to where the prefix will be output to. 389 * 390 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 391 * @retval OT_ERROR_NONE Successfully retrieved the NAT64 prefix. 392 * 393 */ 394 otError otBorderRoutingGetNat64Prefix(otInstance *aInstance, otIp6Prefix *aPrefix); 395 396 /** 397 * Gets the currently favored NAT64 prefix. 398 * 399 * The favored NAT64 prefix can be discovered from infrastructure link or can be this device's local NAT64 prefix. 400 * 401 * @param[in] aInstance A pointer to an OpenThread instance. 402 * @param[out] aPrefix A pointer to output the favored NAT64 prefix. 403 * @param[out] aPreference A pointer to output the preference associated the favored prefix. 404 * 405 * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. 406 * @retval OT_ERROR_NONE Successfully retrieved the favored NAT64 prefix. 407 * 408 */ 409 otError otBorderRoutingGetFavoredNat64Prefix(otInstance *aInstance, 410 otIp6Prefix *aPrefix, 411 otRoutePreference *aPreference); 412 413 /** 414 * Initializes an `otBorderRoutingPrefixTableIterator`. 415 * 416 * An iterator MUST be initialized before it is used. 417 * 418 * An iterator can be initialized again to restart from the beginning of the table. 419 * 420 * When iterating over entries in the table, to ensure the update times `mMsecSinceLastUpdate` of entries are 421 * consistent, they are given relative to the time the iterator was initialized. 422 * 423 * @param[in] aInstance The OpenThread instance. 424 * @param[out] aIterator A pointer to the iterator to initialize. 425 * 426 */ 427 void otBorderRoutingPrefixTableInitIterator(otInstance *aInstance, otBorderRoutingPrefixTableIterator *aIterator); 428 429 /** 430 * Iterates over the entries in the Border Router's discovered prefix table. 431 * 432 * Prefix entries associated with the same discovered router on an infrastructure link are guaranteed to be grouped 433 * together (retrieved back-to-back). 434 * 435 * @param[in] aInstance The OpenThread instance. 436 * @param[in,out] aIterator A pointer to the iterator. 437 * @param[out] aEntry A pointer to the entry to populate. 438 * 439 * @retval OT_ERROR_NONE Iterated to the next entry, @p aEntry and @p aIterator are updated. 440 * @retval OT_ERROR_NOT_FOUND No more entries in the table. 441 * 442 */ 443 otError otBorderRoutingGetNextPrefixTableEntry(otInstance *aInstance, 444 otBorderRoutingPrefixTableIterator *aIterator, 445 otBorderRoutingPrefixTableEntry *aEntry); 446 447 /** 448 * Iterates over the discovered router entries on the infrastructure link. 449 * 450 * @param[in] aInstance The OpenThread instance. 451 * @param[in,out] aIterator A pointer to the iterator. 452 * @param[out] aEntry A pointer to the entry to populate. 453 * 454 * @retval OT_ERROR_NONE Iterated to the next router, @p aEntry and @p aIterator are updated. 455 * @retval OT_ERROR_NOT_FOUND No more router entries. 456 * 457 */ 458 otError otBorderRoutingGetNextRouterEntry(otInstance *aInstance, 459 otBorderRoutingPrefixTableIterator *aIterator, 460 otBorderRoutingRouterEntry *aEntry); 461 462 /** 463 * Enables / Disables DHCPv6 Prefix Delegation. 464 * 465 * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled. 466 * 467 * @param[in] aInstance A pointer to an OpenThread instance. 468 * @param[in] aEnabled Whether to accept platform generated RA messages. 469 * 470 */ 471 void otBorderRoutingDhcp6PdSetEnabled(otInstance *aInstance, bool aEnabled); 472 473 /** 474 * Gets the current state of DHCPv6 Prefix Delegation. 475 * 476 * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` to be enabled. 477 * 478 * @param[in] aInstance A pointer to an OpenThread instance. 479 * 480 * @returns The current state of DHCPv6 Prefix Delegation. 481 * 482 */ 483 otBorderRoutingDhcp6PdState otBorderRoutingDhcp6PdGetState(otInstance *aInstance); 484 485 /** 486 * @} 487 * 488 */ 489 490 #ifdef __cplusplus 491 } // extern "C" 492 #endif 493 494 #endif // OPENTHREAD_BORDER_ROUTING_H_ 495