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    mData0;
89     uint32_t    mData1;
90     uint8_t     mData2;
91     uint8_t     mData3;
92 } otBorderRoutingPrefixTableIterator;
93 
94 /**
95  * Represents a discovered router on the infrastructure link.
96  *
97  * The `mIsPeerBr` field requires `OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE`. Routing Manager
98  * determines whether the router is a peer BR (connected to the same Thread mesh network) by comparing its advertised
99  * PIO/RIO prefixes with the entries in the Thread Network Data. While this method is generally effective, it may not
100  * be 100% accurate in all scenarios, so the `mIsPeerBr` flag should be used with caution.
101  *
102  */
103 typedef struct otBorderRoutingRouterEntry
104 {
105     otIp6Address mAddress;                      ///< IPv6 address of the router.
106     uint32_t     mMsecSinceLastUpdate;          ///< Milliseconds since last update (any message rx) from this router.
107     uint32_t     mAge;                          ///< The router's age in seconds (duration since its first discovery).
108     bool         mManagedAddressConfigFlag : 1; ///< The router's Managed Address Config flag (`M` flag).
109     bool         mOtherConfigFlag : 1;          ///< The router's Other Config flag (`O` flag).
110     bool         mStubRouterFlag : 1;           ///< The router's Stub Router flag.
111     bool         mIsLocalDevice : 1;            ///< This router is the local device (this BR).
112     bool         mIsReachable : 1;              ///< This router is reachable.
113     bool         mIsPeerBr : 1;                 ///< This router is (likely) a peer BR.
114 } otBorderRoutingRouterEntry;
115 
116 /**
117  * Represents an entry from the discovered prefix table.
118  *
119  * The entries in the discovered table track the Prefix/Route Info Options in the received Router Advertisement messages
120  * from other routers on the infrastructure link.
121  *
122  */
123 typedef struct otBorderRoutingPrefixTableEntry
124 {
125     otBorderRoutingRouterEntry mRouter;              ///< Information about the router advertising this prefix.
126     otIp6Prefix                mPrefix;              ///< The discovered IPv6 prefix.
127     bool                       mIsOnLink;            ///< Indicates whether the prefix is on-link or route prefix.
128     uint32_t                   mMsecSinceLastUpdate; ///< Milliseconds since last update of this prefix.
129     uint32_t                   mValidLifetime;       ///< Valid lifetime of the prefix (in seconds).
130     otRoutePreference          mRoutePreference;     ///< Route preference when `mIsOnlink` is false.
131     uint32_t                   mPreferredLifetime;   ///< Preferred lifetime of the on-link prefix when `mIsOnLink`.
132 } otBorderRoutingPrefixTableEntry;
133 
134 /**
135  * Represents information about a peer Border Router found in the Network Data.
136  *
137  */
138 typedef struct otBorderRoutingPeerBorderRouterEntry
139 {
140     uint16_t mRloc16; ///< The RLOC16 of BR.
141     uint32_t mAge;    ///< Seconds since the BR appeared in the Network Data.
142 } otBorderRoutingPeerBorderRouterEntry;
143 
144 /**
145  * Represents a group of data of platform-generated RA messages processed.
146  *
147  */
148 typedef struct otPdProcessedRaInfo
149 {
150     uint32_t mNumPlatformRaReceived;   ///< The number of platform generated RA handled by ProcessPlatformGeneratedRa.
151     uint32_t mNumPlatformPioProcessed; ///< The number of PIO processed for adding OMR prefixes.
152     uint32_t mLastPlatformRaMsec;      ///< The timestamp of last processed RA message.
153 } otPdProcessedRaInfo;
154 
155 /**
156  * Represents the state of Border Routing Manager.
157  *
158  */
159 typedef enum
160 {
161     OT_BORDER_ROUTING_STATE_UNINITIALIZED, ///< Routing Manager is uninitialized.
162     OT_BORDER_ROUTING_STATE_DISABLED,      ///< Routing Manager is initialized but disabled.
163     OT_BORDER_ROUTING_STATE_STOPPED,       ///< Routing Manager in initialized and enabled but currently stopped.
164     OT_BORDER_ROUTING_STATE_RUNNING,       ///< Routing Manager is initialized, enabled, and running.
165 } otBorderRoutingState;
166 
167 /**
168  * This enumeration represents the state of DHCPv6 Prefix Delegation State.
169  *
170  */
171 typedef enum
172 {
173     OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED, ///< DHCPv6 PD is disabled on the border router.
174     OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED,  ///< DHCPv6 PD in enabled but won't try to request and publish a prefix.
175     OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING,  ///< DHCPv6 PD is enabled and will try to request and publish a prefix.
176 } otBorderRoutingDhcp6PdState;
177 
178 /**
179  * Initializes the Border Routing Manager on given infrastructure interface.
180  *
181  * @note  This method MUST be called before any other otBorderRouting* APIs.
182  * @note  This method can be re-called to change the infrastructure interface, but the Border Routing Manager should be
183  *        disabled first, and re-enabled after.
184  *
185  * @param[in]  aInstance          A pointer to an OpenThread instance.
186  * @param[in]  aInfraIfIndex      The infrastructure interface index.
187  * @param[in]  aInfraIfIsRunning  A boolean that indicates whether the infrastructure
188  *                                interface is running.
189  *
190  * @retval  OT_ERROR_NONE           Successfully started the Border Routing Manager on given infrastructure.
191  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is in a state other than disabled or uninitialized.
192  * @retval  OT_ERROR_INVALID_ARGS   The index of the infrastructure interface is not valid.
193  * @retval  OT_ERROR_FAILED         Internal failure. Usually due to failure in generating random prefixes.
194  *
195  * @sa otPlatInfraIfStateChanged.
196  * @sa otBorderRoutingSetEnabled.
197  *
198  */
199 otError otBorderRoutingInit(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning);
200 
201 /**
202  * Enables or disables the Border Routing Manager.
203  *
204  * @note  The Border Routing Manager is disabled by default.
205  *
206  * @param[in]  aInstance  A pointer to an OpenThread instance.
207  * @param[in]  aEnabled   A boolean to enable/disable the routing manager.
208  *
209  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
210  * @retval  OT_ERROR_NONE           Successfully enabled/disabled the Border Routing Manager.
211  *
212  */
213 otError otBorderRoutingSetEnabled(otInstance *aInstance, bool aEnabled);
214 
215 /**
216  * Gets the current state of Border Routing Manager.
217  *
218  * @param[in]  aInstance  A pointer to an OpenThread instance.
219  *
220  * @returns The current state of Border Routing Manager.
221  *
222  */
223 otBorderRoutingState otBorderRoutingGetState(otInstance *aInstance);
224 
225 /**
226  * Gets the current preference used when advertising Route Info Options (RIO) in Router Advertisement
227  * messages sent over the infrastructure link.
228  *
229  * The RIO preference is determined as follows:
230  *
231  * - If explicitly set by user by calling `otBorderRoutingSetRouteInfoOptionPreference()`, the given preference is
232  *   used.
233  * - Otherwise, it is determined based on device's current role: Medium preference when in router/leader role and
234  *   low preference when in child role.
235  *
236  * @returns The current Route Info Option preference.
237  *
238  */
239 otRoutePreference otBorderRoutingGetRouteInfoOptionPreference(otInstance *aInstance);
240 
241 /**
242  * Explicitly sets the preference to use when advertising Route Info Options (RIO) in Router
243  * Advertisement messages sent over the infrastructure link.
244  *
245  * After a call to this function, BR will use the given preference for all its advertised RIOs. The preference can be
246  * cleared by calling `otBorderRoutingClearRouteInfoOptionPreference()`.
247  *
248  * @param[in] aInstance     A pointer to an OpenThread instance.
249  * @param[in] aPreference   The route preference to use.
250  *
251  */
252 void otBorderRoutingSetRouteInfoOptionPreference(otInstance *aInstance, otRoutePreference aPreference);
253 
254 /**
255  * Clears a previously set preference value for advertised Route Info Options.
256  *
257  * After a call to this function, BR will use device's role to determine the RIO preference: Medium preference when
258  * in router/leader role and low preference when in child role.
259  *
260  * @param[in] aInstance     A pointer to an OpenThread instance.
261  *
262  */
263 void otBorderRoutingClearRouteInfoOptionPreference(otInstance *aInstance);
264 
265 /**
266  * Sets additional options to append at the end of emitted Router Advertisement (RA) messages.
267  *
268  * The content of @p aOptions is copied internally, so it can be a temporary buffer (e.g., a stack allocated array).
269  *
270  * Subsequent calls to this function overwrite the previously set value.
271  *
272  * @param[in] aOptions   A pointer to the encoded options. Can be `NULL` to clear.
273  * @param[in] aLength    Number of bytes in @p aOptions.
274  *
275  * @retval OT_ERROR_NONE     Successfully set the extra option bytes.
276  * @retval OT_ERROR_NO_BUFS  Could not allocate buffer to save the buffer.
277  *
278  */
279 otError otBorderRoutingSetExtraRouterAdvertOptions(otInstance *aInstance, const uint8_t *aOptions, uint16_t aLength);
280 
281 /**
282  * Gets the current preference used for published routes in Network Data.
283  *
284  * The preference is determined as follows:
285  *
286  * - If explicitly set by user by calling `otBorderRoutingSetRoutePreference()`, the given preference is used.
287  * - Otherwise, it is determined automatically by `RoutingManager` based on the device's role and link quality.
288  *
289  * @param[in] aInstance     A pointer to an OpenThread instance.
290  *
291  * @returns The current published route preference.
292  *
293  */
294 otRoutePreference otBorderRoutingGetRoutePreference(otInstance *aInstance);
295 
296 /**
297  * Explicitly sets the preference of published routes in Network Data.
298  *
299  * After a call to this function, BR will use the given preference. The preference can be cleared by calling
300  * `otBorderRoutingClearRoutePreference()`.
301  *
302  * @param[in] aInstance     A pointer to an OpenThread instance.
303  * @param[in] aPreference   The route preference to use.
304  *
305  */
306 void otBorderRoutingSetRoutePreference(otInstance *aInstance, otRoutePreference aPreference);
307 
308 /**
309  * Clears a previously set preference value for published routes in Network Data.
310  *
311  * After a call to this function, BR will determine the preference automatically based on the device's role and
312  * link quality (to the parent when acting as end-device).
313  *
314  * @param[in] aInstance     A pointer to an OpenThread instance.
315  *
316  */
317 void otBorderRoutingClearRoutePreference(otInstance *aInstance);
318 
319 /**
320  * Gets the local Off-Mesh-Routable (OMR) Prefix, for example `fdfc:1ff5:1512:5622::/64`.
321  *
322  * An OMR Prefix is a randomly generated 64-bit prefix that's published in the
323  * Thread network if there isn't already an OMR prefix. This prefix can be reached
324  * from the local Wi-Fi or Ethernet network.
325  *
326  * Note: When DHCPv6 PD is enabled, the border router may publish the prefix from
327  * DHCPv6 PD.
328  *
329  * @param[in]   aInstance  A pointer to an OpenThread instance.
330  * @param[out]  aPrefix    A pointer to where the prefix will be output to.
331  *
332  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
333  * @retval  OT_ERROR_NONE           Successfully retrieved the OMR prefix.
334  *
335  * @sa otBorderRoutingGetPdOmrPrefix
336  *
337  */
338 otError otBorderRoutingGetOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix);
339 
340 /**
341  * Gets the DHCPv6 Prefix Delegation (PD) provided off-mesh-routable (OMR) prefix.
342  *
343  * Only mPrefix, mValidLifetime and mPreferredLifetime fields are used in the returned prefix info.
344  *
345  * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled.
346  *
347  * @param[in]   aInstance    A pointer to an OpenThread instance.
348  * @param[out]  aPrefixInfo  A pointer to where the prefix info will be output to.
349  *
350  * @retval  OT_ERROR_NONE           Successfully retrieved the OMR prefix.
351  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
352  * @retval  OT_ERROR_NOT_FOUND      There are no valid PD prefix on this BR.
353  *
354  * @sa otBorderRoutingGetOmrPrefix
355  * @sa otPlatBorderRoutingProcessIcmp6Ra
356  *
357  */
358 otError otBorderRoutingGetPdOmrPrefix(otInstance *aInstance, otBorderRoutingPrefixTableEntry *aPrefixInfo);
359 
360 /**
361  * Gets the data of platform generated RA message processed..
362  *
363  * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled.
364  *
365  * @param[in]   aInstance    A pointer to an OpenThread instance.
366  * @param[out]  aPrefixInfo  A pointer to where the prefix info will be output to.
367  *
368  * @retval  OT_ERROR_NONE           Successfully retrieved the Info.
369  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
370  * @retval  OT_ERROR_NOT_FOUND      There are no valid Info on this BR.
371  *
372  */
373 otError otBorderRoutingGetPdProcessedRaInfo(otInstance *aInstance, otPdProcessedRaInfo *aPdProcessedRaInfo);
374 
375 /**
376  * Gets the currently favored Off-Mesh-Routable (OMR) Prefix.
377  *
378  * The favored OMR prefix can be discovered from Network Data or can be this device's local OMR prefix.
379  *
380  * @param[in]   aInstance    A pointer to an OpenThread instance.
381  * @param[out]  aPrefix      A pointer to output the favored OMR prefix.
382  * @param[out]  aPreference  A pointer to output the preference associated the favored prefix.
383  *
384  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not running yet.
385  * @retval  OT_ERROR_NONE           Successfully retrieved the favored OMR prefix.
386  *
387  */
388 otError otBorderRoutingGetFavoredOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix, otRoutePreference *aPreference);
389 
390 /**
391  * Gets the local On-Link Prefix for the adjacent infrastructure link.
392  *
393  * The local On-Link Prefix is a 64-bit prefix that's advertised on the infrastructure link if there isn't already a
394  * usable on-link prefix being advertised on the link.
395  *
396  * @param[in]   aInstance  A pointer to an OpenThread instance.
397  * @param[out]  aPrefix    A pointer to where the prefix will be output to.
398  *
399  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
400  * @retval  OT_ERROR_NONE           Successfully retrieved the local on-link prefix.
401  *
402  */
403 otError otBorderRoutingGetOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPrefix);
404 
405 /**
406  * Gets the currently favored On-Link Prefix.
407  *
408  * The favored prefix is either a discovered on-link prefix on the infrastructure link or the local on-link prefix.
409  *
410  * @param[in]   aInstance  A pointer to an OpenThread instance.
411  * @param[out]  aPrefix    A pointer to where the prefix will be output to.
412  *
413  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
414  * @retval  OT_ERROR_NONE           Successfully retrieved the favored on-link prefix.
415  *
416  */
417 otError otBorderRoutingGetFavoredOnLinkPrefix(otInstance *aInstance, otIp6Prefix *aPrefix);
418 
419 /**
420  * Gets the local NAT64 Prefix of the Border Router.
421  *
422  * NAT64 Prefix might not be advertised in the Thread network.
423  *
424  * `OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE` must be enabled.
425  *
426  * @param[in]   aInstance   A pointer to an OpenThread instance.
427  * @param[out]  aPrefix     A pointer to where the prefix will be output to.
428  *
429  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
430  * @retval  OT_ERROR_NONE           Successfully retrieved the NAT64 prefix.
431  *
432  */
433 otError otBorderRoutingGetNat64Prefix(otInstance *aInstance, otIp6Prefix *aPrefix);
434 
435 /**
436  * Gets the currently favored NAT64 prefix.
437  *
438  * The favored NAT64 prefix can be discovered from infrastructure link or can be this device's local NAT64 prefix.
439  *
440  * @param[in]   aInstance    A pointer to an OpenThread instance.
441  * @param[out]  aPrefix      A pointer to output the favored NAT64 prefix.
442  * @param[out]  aPreference  A pointer to output the preference associated the favored prefix.
443  *
444  * @retval  OT_ERROR_INVALID_STATE  The Border Routing Manager is not initialized yet.
445  * @retval  OT_ERROR_NONE           Successfully retrieved the favored NAT64 prefix.
446  *
447  */
448 otError otBorderRoutingGetFavoredNat64Prefix(otInstance        *aInstance,
449                                              otIp6Prefix       *aPrefix,
450                                              otRoutePreference *aPreference);
451 
452 /**
453  * Initializes an `otBorderRoutingPrefixTableIterator`.
454  *
455  * An iterator MUST be initialized before it is used.
456  *
457  * An iterator can be initialized again to restart from the beginning of the table.
458  *
459  * When iterating over entries in the table, to ensure the update times `mMsecSinceLastUpdate` of entries are
460  * consistent, they are given relative to the time the iterator was initialized.
461  *
462  * @param[in]  aInstance  The OpenThread instance.
463  * @param[out] aIterator  A pointer to the iterator to initialize.
464  *
465  */
466 void otBorderRoutingPrefixTableInitIterator(otInstance *aInstance, otBorderRoutingPrefixTableIterator *aIterator);
467 
468 /**
469  * Iterates over the entries in the Border Router's discovered prefix table.
470  *
471  * Prefix entries associated with the same discovered router on an infrastructure link are guaranteed to be grouped
472  * together (retrieved back-to-back).
473  *
474  * @param[in]     aInstance    The OpenThread instance.
475  * @param[in,out] aIterator    A pointer to the iterator.
476  * @param[out]    aEntry       A pointer to the entry to populate.
477  *
478  * @retval OT_ERROR_NONE        Iterated to the next entry, @p aEntry and @p aIterator are updated.
479  * @retval OT_ERROR_NOT_FOUND   No more entries in the table.
480  *
481  */
482 otError otBorderRoutingGetNextPrefixTableEntry(otInstance                         *aInstance,
483                                                otBorderRoutingPrefixTableIterator *aIterator,
484                                                otBorderRoutingPrefixTableEntry    *aEntry);
485 
486 /**
487  * Iterates over the discovered router entries on the infrastructure link.
488  *
489  * @param[in]     aInstance    The OpenThread instance.
490  * @param[in,out] aIterator    A pointer to the iterator.
491  * @param[out]    aEntry       A pointer to the entry to populate.
492  *
493  * @retval OT_ERROR_NONE        Iterated to the next router, @p aEntry and @p aIterator are updated.
494  * @retval OT_ERROR_NOT_FOUND   No more router entries.
495  *
496  */
497 otError otBorderRoutingGetNextRouterEntry(otInstance                         *aInstance,
498                                           otBorderRoutingPrefixTableIterator *aIterator,
499                                           otBorderRoutingRouterEntry         *aEntry);
500 
501 /**
502  * Iterates over the peer BRs found in the Network Data.
503  *
504  * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE`.
505  *
506  * Peer BRs are other devices within the Thread mesh that provide external IP connectivity. A device is considered
507  * to provide external IP connectivity if at least one of the following conditions is met regarding its Network Data
508  * entries:
509  *
510  * - It has added at least one external route entry.
511  * - It has added at least one prefix entry with both the default-route and on-mesh flags set.
512  * - It has added at least one domain prefix (with both the domain and on-mesh flags set).
513  *
514  * The list of peer BRs specifically excludes the current device, even if it is itself acting as a BR.
515  *
516  * @param[in]     aInstance    The OpenThread instance.
517  * @param[in,out] aIterator    A pointer to the iterator.
518  * @param[out]    aEntry       A pointer to the entry to populate.
519  *
520  * @retval OT_ERROR_NONE        Iterated to the next entry, @p aEntry and @p aIterator are updated.
521  * @retval OT_ERROR_NOT_FOUND   No more entries.
522  *
523  */
524 otError otBorderRoutingGetNextPeerBrEntry(otInstance                           *aInstance,
525                                           otBorderRoutingPrefixTableIterator   *aIterator,
526                                           otBorderRoutingPeerBorderRouterEntry *aEntry);
527 
528 /**
529  * Returns the number of peer BRs found in the Network Data.
530  *
531  * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE`.
532  *
533  * Peer BRs are other devices within the Thread mesh that provide external IP connectivity. A device is considered
534  * to provide external IP connectivity if at least one of the following conditions is met regarding its Network Data
535  * entries:
536  *
537  * - It has added at least one external route entry.
538  * - It has added at least one prefix entry with both the default-route and on-mesh flags set.
539  * - It has added at least one domain prefix (with both the domain and on-mesh flags set).
540  *
541  * The list of peer BRs specifically excludes the current device, even if it is itself acting as a BR.
542  *
543  * @param[in]  aInstance    The OpenThread instance.
544  * @param[out] aMinAge      Pointer to an `uint32_t` to return the minimum age among all peer BRs.
545  *                          Can be NULL if the caller does not need this information.
546  *                          Age is represented as seconds since appearance of the BR entry in the Network Data.
547  *
548  * @returns The number of peer BRs.
549  *
550  */
551 uint16_t otBorderRoutingCountPeerBrs(otInstance *aInstance, uint32_t *aMinAge);
552 
553 /**
554  * Enables / Disables DHCPv6 Prefix Delegation.
555  *
556  * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled.
557  *
558  * @param[in] aInstance A pointer to an OpenThread instance.
559  * @param[in] aEnabled  Whether to accept platform generated RA messages.
560  *
561  */
562 void otBorderRoutingDhcp6PdSetEnabled(otInstance *aInstance, bool aEnabled);
563 
564 /**
565  * Gets the current state of DHCPv6 Prefix Delegation.
566  *
567  * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` to be enabled.
568  *
569  * @param[in]  aInstance  A pointer to an OpenThread instance.
570  *
571  * @returns The current state of DHCPv6 Prefix Delegation.
572  *
573  */
574 otBorderRoutingDhcp6PdState otBorderRoutingDhcp6PdGetState(otInstance *aInstance);
575 
576 /**
577  * When the state of a DHCPv6 Prefix Delegation (PD) on the Thread interface changes, this callback notifies processes
578  * in the OS of this changed state.
579  *
580  * @param[in] aState    The state of DHCPv6 Prefix Delegation State.
581  * @param[in] aContext  A pointer to arbitrary context information.
582  *
583  */
584 typedef void (*otBorderRoutingRequestDhcp6PdCallback)(otBorderRoutingDhcp6PdState aState, void *aContext);
585 
586 /**
587  * Sets the callback whenever the DHCPv6 PD state changes on the Thread interface.
588  *
589  * Subsequent calls to this function replace the previously set callback.
590  *
591  * @param[in] aInstance  A pointer to an OpenThread instance.
592  * @param[in] aCallback  A pointer to a function that is called whenever the DHCPv6 PD state changes.
593  * @param[in] aContext   A pointer to arbitrary context information.
594  *
595  *
596  */
597 void otBorderRoutingDhcp6PdSetRequestCallback(otInstance                           *aInstance,
598                                               otBorderRoutingRequestDhcp6PdCallback aCallback,
599                                               void                                 *aContext);
600 
601 /**
602  * Sets the local on-link prefix.
603  *
604  * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_TESTING_API_ENABLE`.
605  *
606  * This is intended for testing only and using it will make the BR non-compliant with the Thread Specification.
607  *
608  * @param[in]  aPrefix      The on-link prefix to use.
609  *
610  */
611 void otBorderRoutingSetOnLinkPrefix(otInstance *aInstance, const otIp6Prefix *aPrefix);
612 
613 /**
614  * @}
615  *
616  */
617 
618 #ifdef __cplusplus
619 } // extern "C"
620 #endif
621 
622 #endif // OPENTHREAD_BORDER_ROUTING_H_
623