1 /*
2  *  Copyright (c) 2020, 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  *   This file includes definitions for the RA-based routing management.
32  *
33  */
34 
35 #ifndef ROUTING_MANAGER_HPP_
36 #define ROUTING_MANAGER_HPP_
37 
38 #include "openthread-core-config.h"
39 
40 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
41 
42 #if !OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
43 #error "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE is required for OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE."
44 #endif
45 
46 #if !OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
47 #error "OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE is required for OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE."
48 #endif
49 
50 #include <openthread/nat64.h>
51 #include <openthread/netdata.h>
52 
53 #include "border_router/infra_if.hpp"
54 #include "common/array.hpp"
55 #include "common/error.hpp"
56 #include "common/linked_list.hpp"
57 #include "common/locator.hpp"
58 #include "common/notifier.hpp"
59 #include "common/pool.hpp"
60 #include "common/string.hpp"
61 #include "common/timer.hpp"
62 #include "net/ip6.hpp"
63 #include "net/nat64_translator.hpp"
64 #include "net/nd6.hpp"
65 #include "thread/network_data.hpp"
66 
67 namespace ot {
68 
69 namespace BorderRouter {
70 
71 /**
72  * This class implements bi-directional routing between Thread and Infrastructure networks.
73  *
74  * The Border Routing manager works on both Thread interface and infrastructure interface.
75  * All ICMPv6 messages are sent/received on the infrastructure interface.
76  *
77  */
78 class RoutingManager : public InstanceLocator
79 {
80     friend class ot::Notifier;
81     friend class ot::Instance;
82 
83 public:
84     typedef NetworkData::RoutePreference       RoutePreference;     ///< Route preference (high, medium, low).
85     typedef otBorderRoutingPrefixTableIterator PrefixTableIterator; ///< Prefix Table Iterator.
86     typedef otBorderRoutingPrefixTableEntry    PrefixTableEntry;    ///< Prefix Table Entry.
87 
88     /**
89      * This constant specifies the maximum number of route prefixes that may be published by `RoutingManager`
90      * in Thread Network Data.
91      *
92      * This is used by `NetworkData::Publisher` to reserve entries for use by `RoutingManager`.
93      *
94      * The number of published entries accounts for:
95      * - Route prefix `fc00::/7` or `::/0`
96      * - One entry for NAT64 published prefix.
97      * - One extra entry for transitions.
98      *
99      */
100     static constexpr uint16_t kMaxPublishedPrefixes = 3;
101 
102     /**
103      * This enumeration represents the states of `RoutingManager`.
104      *
105      */
106     enum State : uint8_t
107     {
108         kStateUninitialized = OT_BORDER_ROUTING_STATE_UNINITIALIZED, ///< Uninitialized.
109         kStateDisabled      = OT_BORDER_ROUTING_STATE_DISABLED,      ///< Initialized but disabled.
110         kStateStopped       = OT_BORDER_ROUTING_STATE_STOPPED,       ///< Initialized & enabled, but currently stopped.
111         kStateRunning       = OT_BORDER_ROUTING_STATE_RUNNING,       ///< Initialized, enabled, and running.
112     };
113 
114     /**
115      * This constructor initializes the routing manager.
116      *
117      * @param[in]  aInstance  A OpenThread instance.
118      *
119      */
120     explicit RoutingManager(Instance &aInstance);
121 
122     /**
123      * This method initializes the routing manager on given infrastructure interface.
124      *
125      * @param[in]  aInfraIfIndex      An infrastructure network interface index.
126      * @param[in]  aInfraIfIsRunning  A boolean that indicates whether the infrastructure
127      *                                interface is running.
128      *
129      * @retval  kErrorNone         Successfully started the routing manager.
130      * @retval  kErrorInvalidArgs  The index of the infra interface is not valid.
131      *
132      */
133     Error Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning);
134 
135     /**
136      * This method enables/disables the Border Routing Manager.
137      *
138      * @note  The Border Routing Manager is enabled by default.
139      *
140      * @param[in]  aEnabled   A boolean to enable/disable the Border Routing Manager.
141      *
142      * @retval  kErrorInvalidState   The Border Routing Manager is not initialized yet.
143      * @retval  kErrorNone           Successfully enabled/disabled the Border Routing Manager.
144      *
145      */
146     Error SetEnabled(bool aEnabled);
147 
148     /**
149      * This method indicates whether or not it is currently running.
150      *
151      * In order for the `RoutingManager` to be running it needs to be initialized and enabled, and device being
152      * attached.
153      *
154      * @retval TRUE  The RoutingManager is currently running.
155      * @retval FALSE The RoutingManager is not running.
156      *
157      */
IsRunning(void) const158     bool IsRunning(void) const { return mIsRunning; }
159 
160     /**
161      * This method gets the state of `RoutingManager`.
162      *
163      * @returns The current state of `RoutingManager`.
164      *
165      */
166     State GetState(void) const;
167 
168     /**
169      * This method requests the Border Routing Manager to stop.
170      *
171      * If Border Routing Manager is running, calling this method immediately stops it and triggers the preparation
172      * and sending of a final Router Advertisement (RA) message on infrastructure interface which deprecates and/or
173      * removes any previously advertised PIO/RIO prefixes. If Routing Manager is not running (or not enabled), no
174      * action is taken.
175      *
176      * Note that this method does not change whether the Routing Manager is enabled or disabled (see `SetEnabled()`).
177      * It stops the Routing Manager temporarily. After calling this method if the device role gets changes (device
178      * gets attached) and/or the infra interface state gets changed, the Routing Manager may be started again.
179      *
180      */
RequestStop(void)181     void RequestStop(void) { Stop(); }
182 
183     /**
184      * This method gets the current preference used when advertising Route Info Options (RIO) in Router Advertisement
185      * messages sent over the infrastructure link.
186      *
187      * The RIO preference is determined as follows:
188      *
189      * - If explicitly set by user by calling `SetRouteInfoOptionPreference()`, the given preference is used.
190      * - Otherwise, it is determined based on device's role: Medium preference when in router/leader role and low
191      *   preference when in child role.
192      *
193      * @returns The current Route Info Option preference.
194      *
195      */
GetRouteInfoOptionPreference(void) const196     RoutePreference GetRouteInfoOptionPreference(void) const { return mRioPreference; }
197 
198     /**
199      * This method explicitly sets the preference to use when advertising Route Info Options (RIO) in Router
200      * Advertisement messages sent over the infrastructure link.
201      *
202      * After a call to this method, BR will use the given preference for all its advertised RIOs. The preference can be
203      * cleared by calling `ClearRouteInfoOptionPreference`()`.
204      *
205      * @param[in] aPreference   The route preference to use.
206      *
207      */
208     void SetRouteInfoOptionPreference(RoutePreference aPreference);
209 
210     /**
211      * This method clears a previously set preference value for advertised Route Info Options.
212      *
213      * After a call to this method, BR will use device role to determine the RIO preference: Medium preference when
214      * in router/leader role and low preference when in child role.
215      *
216      */
217     void ClearRouteInfoOptionPreference(void);
218 
219     /**
220      * This method returns the local off-mesh-routable (OMR) prefix.
221      *
222      * The randomly generated 64-bit prefix will be added to the Thread Network Data if there isn't already an OMR
223      * prefix.
224      *
225      * @param[out]  aPrefix  A reference to where the prefix will be output to.
226      *
227      * @retval  kErrorInvalidState  The Border Routing Manager is not initialized yet.
228      * @retval  kErrorNone          Successfully retrieved the OMR prefix.
229      *
230      */
231     Error GetOmrPrefix(Ip6::Prefix &aPrefix) const;
232 
233     /**
234      * This method returns the currently favored off-mesh-routable (OMR) prefix.
235      *
236      * The favored OMR prefix can be discovered from Network Data or can be our local OMR prefix.
237      *
238      * An OMR prefix with higher preference is favored. If the preference is the same, then the smaller prefix (in the
239      * sense defined by `Ip6::Prefix`) is favored.
240      *
241      * @param[out] aPrefix         A reference to output the favored prefix.
242      * @param[out] aPreference     A reference to output the preference associated with the favored OMR prefix.
243      *
244      * @retval  kErrorInvalidState  The Border Routing Manager is not running yet.
245      * @retval  kErrorNone          Successfully retrieved the OMR prefix.
246      *
247      */
248     Error GetFavoredOmrPrefix(Ip6::Prefix &aPrefix, RoutePreference &aPreference) const;
249 
250     /**
251      * This method returns the on-link prefix for the adjacent infrastructure link.
252      *
253      * The randomly generated 64-bit prefix will be advertised
254      * on the infrastructure link if there isn't already a usable
255      * on-link prefix being advertised on the link.
256      *
257      * @param[out]  aPrefix  A reference to where the prefix will be output to.
258      *
259      * @retval  kErrorInvalidState  The Border Routing Manager is not initialized yet.
260      * @retval  kErrorNone          Successfully retrieved the local on-link prefix.
261      *
262      */
263     Error GetOnLinkPrefix(Ip6::Prefix &aPrefix) const;
264 
265     /**
266      * This method returns the favored on-link prefix for the adjacent infrastructure link.
267      *
268      * The favored prefix is either a discovered prefix on the infrastructure link or the local on-link prefix.
269      *
270      * @param[out]  aPrefix  A reference to where the prefix will be output to.
271      *
272      * @retval  kErrorInvalidState  The Border Routing Manager is not initialized yet.
273      * @retval  kErrorNone          Successfully retrieved the favored on-link prefix.
274      *
275      */
276     Error GetFavoredOnLinkPrefix(Ip6::Prefix &aPrefix) const;
277 
278 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
279     /**
280      * Gets the state of NAT64 prefix publishing.
281      *
282      * @retval  kStateDisabled   NAT64 is disabled.
283      * @retval  kStateNotRunning NAT64 is enabled, but is not running since routing manager is not running.
284      * @retval  kStateIdle       NAT64 is enabled, but the border router is not publishing a NAT64 prefix. Usually
285      *                           when there is another border router publishing a NAT64 prefix with higher
286      *                           priority.
287      * @retval  kStateActive     The Border router is publishing a NAT64 prefix.
288      *
289      */
GetNat64PrefixManagerState(void) const290     Nat64::State GetNat64PrefixManagerState(void) const { return mNat64PrefixManager.GetState(); }
291 
292     /**
293      * Enable or disable NAT64 prefix publishing.
294      *
295      * @param[in]  aEnabled   A boolean to enable/disable NAT64 prefix publishing.
296      *
297      */
298     void SetNat64PrefixManagerEnabled(bool aEnabled);
299 
300     /**
301      * This method returns the local NAT64 prefix.
302      *
303      * @param[out]  aPrefix  A reference to where the prefix will be output to.
304      *
305      * @retval  kErrorInvalidState  The Border Routing Manager is not initialized yet.
306      * @retval  kErrorNone          Successfully retrieved the NAT64 prefix.
307      *
308      */
309     Error GetNat64Prefix(Ip6::Prefix &aPrefix);
310 
311     /**
312      * This method returns the currently favored NAT64 prefix.
313      *
314      * The favored NAT64 prefix can be discovered from infrastructure link or can be the local NAT64 prefix.
315      *
316      * @param[out] aPrefix         A reference to output the favored prefix.
317      * @param[out] aPreference     A reference to output the preference associated with the favored prefix.
318      *
319      * @retval  kErrorInvalidState  The Border Routing Manager is not initialized yet.
320      * @retval  kErrorNone          Successfully retrieved the NAT64 prefix.
321      *
322      */
323     Error GetFavoredNat64Prefix(Ip6::Prefix &aPrefix, RoutePreference &aRoutePreference);
324 
325     /**
326      * This method informs `RoutingManager` of the result of the discovery request of NAT64 prefix on infrastructure
327      * interface (`InfraIf::DiscoverNat64Prefix()`).
328      *
329      * @param[in]  aPrefix  The discovered NAT64 prefix on `InfraIf`.
330      *
331      */
HandleDiscoverNat64PrefixDone(const Ip6::Prefix & aPrefix)332     void HandleDiscoverNat64PrefixDone(const Ip6::Prefix &aPrefix) { mNat64PrefixManager.HandleDiscoverDone(aPrefix); }
333 
334 #endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
335 
336     /**
337      * This method processes a received ICMPv6 message from the infrastructure interface.
338      *
339      * Malformed or undesired messages are dropped silently.
340      *
341      * @param[in]  aPacket        The received ICMPv6 packet.
342      * @param[in]  aSrcAddress    The source address this message is sent from.
343      *
344      */
345     void HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
346 
347     /**
348      * This method handles infrastructure interface state changes.
349      *
350      */
HandleInfraIfStateChanged(void)351     void HandleInfraIfStateChanged(void) { EvaluateState(); }
352 
353     /**
354      * This method checks whether the on-mesh prefix configuration is a valid OMR prefix.
355      *
356      * @param[in] aOnMeshPrefixConfig  The on-mesh prefix configuration to check.
357      *
358      * @retval   TRUE    The prefix is a valid OMR prefix.
359      * @retval   FALSE   The prefix is not a valid OMR prefix.
360      *
361      */
362     static bool IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
363 
364     /**
365      * This method checks whether a given prefix is a valid OMR prefix.
366      *
367      * @param[in]  aPrefix  The prefix to check.
368      *
369      * @retval   TRUE    The prefix is a valid OMR prefix.
370      * @retval   FALSE   The prefix is not a valid OMR prefix.
371      *
372      */
373     static bool IsValidOmrPrefix(const Ip6::Prefix &aPrefix);
374 
375     /**
376      * This method initializes a `PrefixTableIterator`.
377      *
378      * An iterator can be initialized again to start from the beginning of the table.
379      *
380      * When iterating over entries in the table, to ensure the entry update times are consistent, they are given
381      * relative to the time the iterator was initialized.
382      *
383      * @param[out] aIterator  The iterator to initialize.
384      *
385      */
InitPrefixTableIterator(PrefixTableIterator & aIterator) const386     void InitPrefixTableIterator(PrefixTableIterator &aIterator) const
387     {
388         mDiscoveredPrefixTable.InitIterator(aIterator);
389     }
390 
391     /**
392      * This method iterates over entries in the discovered prefix table.
393      *
394      * @param[in,out] aIterator  An iterator.
395      * @param[out]    aEntry     A reference to the entry to populate.
396      *
397      * @retval kErrorNone        Got the next entry, @p aEntry is updated and @p aIterator is advanced.
398      * @retval kErrorNotFound    No more entries in the table.
399      *
400      */
GetNextPrefixTableEntry(PrefixTableIterator & aIterator,PrefixTableEntry & aEntry) const401     Error GetNextPrefixTableEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const
402     {
403         return mDiscoveredPrefixTable.GetNextEntry(aIterator, aEntry);
404     }
405 
406 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
407     /**
408      * This method determines whether to enable/disable SRP server when the auto-enable mode is changed on SRP server.
409      *
410      * This should be called from `Srp::Server` when auto-enable mode is changed.
411      *
412      */
413     void HandleSrpServerAutoEnableMode(void);
414 #endif
415 
416 private:
417     static constexpr uint8_t kMaxOnMeshPrefixes = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_ON_MESH_PREFIXES;
418 
419     static constexpr uint8_t kOmrPrefixLength    = OT_IP6_PREFIX_BITSIZE; // The length of an OMR prefix. In bits.
420     static constexpr uint8_t kOnLinkPrefixLength = OT_IP6_PREFIX_BITSIZE; // The length of an On-link prefix. In bits.
421     static constexpr uint8_t kBrUlaPrefixLength  = 48;                    // The length of a BR ULA prefix. In bits.
422     static constexpr uint8_t kNat64PrefixLength  = 96;                    // The length of a NAT64 prefix. In bits.
423 
424     static constexpr uint16_t kOmrPrefixSubnetId   = 1; // The subnet ID of an OMR prefix within a BR ULA prefix.
425     static constexpr uint16_t kNat64PrefixSubnetId = 2; // The subnet ID of a NAT64 prefix within a BR ULA prefix.
426 
427     // The maximum number of initial Router Advertisements.
428     static constexpr uint32_t kMaxInitRtrAdvertisements = 3;
429 
430     static constexpr uint32_t kDefaultOmrPrefixLifetime    = 1800; // The default OMR prefix valid lifetime. In sec.
431     static constexpr uint32_t kDefaultOnLinkPrefixLifetime = 1800; // The default on-link prefix valid lifetime. In sec.
432     static constexpr uint32_t kDefaultNat64PrefixLifetime  = 300;  // The default NAT64 prefix valid lifetime. In sec.
433     static constexpr uint32_t kMaxRtrAdvInterval           = 600;  // Max Router Advertisement Interval. In sec.
434     static constexpr uint32_t kMinRtrAdvInterval           = kMaxRtrAdvInterval / 3; // Min RA Interval. In sec.
435     static constexpr uint32_t kMaxInitRtrAdvInterval       = 16;                     // Max Initial RA Interval. In sec.
436     static constexpr uint32_t kRaReplyJitter               = 500;  // Jitter for sending RA after rx RS. In msec.
437     static constexpr uint32_t kPolicyEvaluationMinDelay    = 2000; // Min delay for policy evaluation. In msec.
438     static constexpr uint32_t kPolicyEvaluationMaxDelay    = 4000; // Max delay for policy evaluation. In msec.
439     static constexpr uint32_t kMinDelayBetweenRtrAdvs      = 3000; // Min delay (msec) between consecutive RAs.
440 
441     // The STALE_RA_TIME in seconds. The Routing Manager will consider the prefixes
442     // and learned RA parameters STALE when they are not refreshed in STALE_RA_TIME
443     // seconds. The Routing Manager will then start Router Solicitation to verify
444     // that the STALE prefix is not being advertised anymore and remove the STALE
445     // prefix.
446     // The value is chosen in range of [`kMaxRtrAdvInterval` upper bound (1800s), `kDefaultOnLinkPrefixLifetime`].
447     static constexpr uint32_t kRtrAdvStaleTime = 1800;
448 
449     static_assert(kMinRtrAdvInterval <= 3 * kMaxRtrAdvInterval / 4, "invalid RA intervals");
450     static_assert(kDefaultOmrPrefixLifetime >= kMaxRtrAdvInterval, "invalid default OMR prefix lifetime");
451     static_assert(kDefaultOnLinkPrefixLifetime >= kMaxRtrAdvInterval, "invalid default on-link prefix lifetime");
452     static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
453                   "invalid RA STALE time");
454     static_assert(kPolicyEvaluationMaxDelay > kPolicyEvaluationMinDelay,
455                   "kPolicyEvaluationMaxDelay must be larger than kPolicyEvaluationMinDelay");
456 
457     enum RouterAdvTxMode : uint8_t // Used in `SendRouterAdvertisement()`
458     {
459         kInvalidateAllPrevPrefixes,
460         kAdvPrefixesFromNetData,
461     };
462 
463     enum ScheduleMode : uint8_t // Used in `ScheduleRoutingPolicyEvaluation()`
464     {
465         kImmediately,
466         kForNextRa,
467         kAfterRandomDelay,
468         kToReplyToRs,
469     };
470 
471     void HandleDiscoveredPrefixTableChanged(void); // Declare early so we can use in `mSignalTask`
HandleDiscoveredPrefixTableEntryTimer(void)472     void HandleDiscoveredPrefixTableEntryTimer(void) { mDiscoveredPrefixTable.HandleEntryTimer(); }
HandleDiscoveredPrefixTableRouterTimer(void)473     void HandleDiscoveredPrefixTableRouterTimer(void) { mDiscoveredPrefixTable.HandleRouterTimer(); }
474 
475     class DiscoveredPrefixTable : public InstanceLocator
476     {
477         // This class maintains the discovered on-link and route prefixes
478         // from the received RA messages by processing PIO and RIO options
479         // from the message. It takes care of processing the RA message but
480         // delegates the decision whether to include or exclude a prefix to
481         // `RoutingManager` by calling its `ShouldProcessPrefixInfoOption()`
482         // and `ShouldProcessRouteInfoOption()` methods.
483         //
484         // It manages the lifetime of the discovered entries and publishes
485         // and unpublishes the prefixes in the Network Data (as external
486         // route) as they are added or removed.
487         //
488         // When there is any change in the table (an entry is added, removed,
489         // or modified), it signals the change to `RoutingManager` by calling
490         // `HandleDiscoveredPrefixTableChanged()` callback. A `Tasklet` is
491         // used for signalling which ensures that if there are multiple
492         // changes within the same flow of execution, the callback is
493         // invoked after all the changes are processed.
494 
495     public:
496         explicit DiscoveredPrefixTable(Instance &aInstance);
497 
498         void ProcessRouterAdvertMessage(const Ip6::Nd::RouterAdvertMessage &aRaMessage,
499                                         const Ip6::Address                 &aSrcAddress);
500         void ProcessNeighborAdvertMessage(const Ip6::Nd::NeighborAdvertMessage &aNaMessage);
501 
502         bool ContainsDefaultOrNonUlaRoutePrefix(void) const;
503         bool ContainsNonUlaOnLinkPrefix(void) const;
504         bool ContainsUlaOnLinkPrefix(void) const;
505 
506         void FindFavoredOnLinkPrefix(Ip6::Prefix &aPrefix) const;
507 
508         void RemoveOnLinkPrefix(const Ip6::Prefix &aPrefix);
509         void RemoveRoutePrefix(const Ip6::Prefix &aPrefix);
510 
511         void RemoveAllEntries(void);
512         void RemoveOrDeprecateOldEntries(TimeMilli aTimeThreshold);
513 
514         TimeMilli CalculateNextStaleTime(TimeMilli aNow) const;
515 
516         void  InitIterator(PrefixTableIterator &aIterator) const;
517         Error GetNextEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const;
518 
519         void HandleEntryTimer(void);
520         void HandleRouterTimer(void);
521 
522     private:
523         static constexpr uint16_t kMaxRouters = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_ROUTERS;
524         static constexpr uint16_t kMaxEntries = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES;
525 
526         class Entry : public LinkedListEntry<Entry>, public Unequatable<Entry>, private Clearable<Entry>
527         {
528             friend class LinkedListEntry<Entry>;
529             friend class Clearable<Entry>;
530 
531         public:
532             enum Type : uint8_t
533             {
534                 kTypeOnLink,
535                 kTypeRoute,
536             };
537 
538             struct Matcher
539             {
Matcherot::BorderRouter::RoutingManager::DiscoveredPrefixTable::Entry::Matcher540                 Matcher(const Ip6::Prefix &aPrefix, Type aType)
541                     : mPrefix(aPrefix)
542                     , mType(aType)
543                 {
544                 }
545 
546                 const Ip6::Prefix &mPrefix;
547                 Type               mType;
548             };
549 
550             struct Checker
551             {
552                 enum Mode : uint8_t
553                 {
554                     kIsUla,
555                     kIsNotUla,
556                 };
557 
Checkerot::BorderRouter::RoutingManager::DiscoveredPrefixTable::Entry::Checker558                 Checker(Mode aMode, Type aType)
559                     : mMode(aMode)
560                     , mType(aType)
561 
562                 {
563                 }
564 
565                 Mode mMode;
566                 Type mType;
567             };
568 
569             struct ExpirationChecker
570             {
ExpirationCheckerot::BorderRouter::RoutingManager::DiscoveredPrefixTable::Entry::ExpirationChecker571                 explicit ExpirationChecker(TimeMilli aNow)
572                     : mNow(aNow)
573                 {
574                 }
575 
576                 TimeMilli mNow;
577             };
578 
579             void               SetFrom(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader);
580             void               SetFrom(const Ip6::Nd::PrefixInfoOption &aPio);
581             void               SetFrom(const Ip6::Nd::RouteInfoOption &aRio);
GetType(void) const582             Type               GetType(void) const { return mType; }
IsOnLinkPrefix(void) const583             bool               IsOnLinkPrefix(void) const { return (mType == kTypeOnLink); }
IsRoutePrefix(void) const584             bool               IsRoutePrefix(void) const { return (mType == kTypeRoute); }
GetPrefix(void) const585             const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
GetLastUpdateTime(void) const586             const TimeMilli   &GetLastUpdateTime(void) const { return mLastUpdateTime; }
GetValidLifetime(void) const587             uint32_t           GetValidLifetime(void) const { return mValidLifetime; }
ClearValidLifetime(void)588             void               ClearValidLifetime(void) { mValidLifetime = 0; }
589             TimeMilli          GetExpireTime(void) const;
590             TimeMilli          GetStaleTime(void) const;
591             RoutePreference    GetPreference(void) const;
592             bool               operator==(const Entry &aOther) const;
593             bool               Matches(const Matcher &aMatcher) const;
594             bool               Matches(const Checker &aChecker) const;
595             bool               Matches(const ExpirationChecker &aChecker) const;
596 
597             // Methods to use when `IsOnLinkPrefix()`
GetPreferredLifetime(void) const598             uint32_t GetPreferredLifetime(void) const { return mShared.mPreferredLifetime; }
ClearPreferredLifetime(void)599             void     ClearPreferredLifetime(void) { mShared.mPreferredLifetime = 0; }
600             bool     IsDeprecated(void) const;
601             void     AdoptValidAndPreferredLifetimesFrom(const Entry &aEntry);
602 
603             // Method to use when `!IsOnlinkPrefix()`
GetRoutePreference(void) const604             RoutePreference GetRoutePreference(void) const { return mShared.mRoutePreference; }
605 
606         private:
607             static uint32_t CalculateExpireDelay(uint32_t aValidLifetime);
608 
609             Entry      *mNext;
610             Ip6::Prefix mPrefix;
611             Type        mType;
612             TimeMilli   mLastUpdateTime;
613             uint32_t    mValidLifetime;
614             union
615             {
616                 uint32_t        mPreferredLifetime; // Applicable when prefix is on-link.
617                 RoutePreference mRoutePreference;   // Applicable when prefix is not on-link
618             } mShared;
619         };
620 
621         struct Router
622         {
623             // The timeout (in msec) for router staying in active state
624             // before starting the Neighbor Solicitation (NS) probes.
625             static constexpr uint32_t kActiveTimeout = OPENTHREAD_CONFIG_BORDER_ROUTING_ROUTER_ACTIVE_CHECK_TIMEOUT;
626 
627             static constexpr uint8_t  kMaxNsProbes          = 5;    // Max number of NS probe attempts.
628             static constexpr uint32_t kNsProbeRetryInterval = 1000; // In msec. Time between NS probe attempts.
629             static constexpr uint32_t kNsProbeTimeout       = 2000; // In msec. Max Wait time after last NS probe.
630             static constexpr uint32_t kJitter               = 2000; // In msec. Jitter to randomize probe starts.
631 
632             static_assert(kMaxNsProbes < 255, "kMaxNsProbes MUST not be 255");
633 
634             enum EmptyChecker : uint8_t
635             {
636                 kContainsNoEntries
637             };
638 
Matchesot::BorderRouter::RoutingManager::DiscoveredPrefixTable::Router639             bool Matches(const Ip6::Address &aAddress) const { return aAddress == mAddress; }
Matchesot::BorderRouter::RoutingManager::DiscoveredPrefixTable::Router640             bool Matches(EmptyChecker) const { return mEntries.IsEmpty(); }
641 
642             Ip6::Address      mAddress;
643             LinkedList<Entry> mEntries;
644             TimeMilli         mTimeout;
645             uint8_t           mNsProbeCount;
646         };
647 
648         class Iterator : public PrefixTableIterator
649         {
650         public:
GetRouter(void) const651             const Router *GetRouter(void) const { return static_cast<const Router *>(mPtr1); }
SetRouter(const Router * aRouter)652             void          SetRouter(const Router *aRouter) { mPtr1 = aRouter; }
GetEntry(void) const653             const Entry  *GetEntry(void) const { return static_cast<const Entry *>(mPtr2); }
SetEntry(const Entry * aEntry)654             void          SetEntry(const Entry *aEntry) { mPtr2 = aEntry; }
GetInitTime(void) const655             TimeMilli     GetInitTime(void) const { return TimeMilli(mData32); }
SetInitTime(void)656             void          SetInitTime(void) { mData32 = TimerMilli::GetNow().GetValue(); }
657         };
658 
659         void         ProcessDefaultRoute(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader, Router &aRouter);
660         void         ProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio, Router &aRouter);
661         void         ProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio, Router &aRouter);
662         bool         Contains(const Entry::Checker &aChecker) const;
663         void         RemovePrefix(const Entry::Matcher &aMatcher);
664         void         RemoveOrDeprecateEntriesFromInactiveRouters(void);
665         void         RemoveRoutersWithNoEntries(void);
AllocateEntry(void)666         Entry       *AllocateEntry(void) { return mEntryPool.Allocate(); }
FreeEntry(Entry & aEntry)667         void         FreeEntry(Entry &aEntry) { mEntryPool.Free(aEntry); }
668         void         FreeEntries(LinkedList<Entry> &aEntries);
669         void         UpdateNetworkDataOnChangeTo(Entry &aEntry);
670         const Entry *FindFavoredEntryToPublish(const Ip6::Prefix &aPrefix) const;
671         void         RemoveExpiredEntries(void);
672         void         SignalTableChanged(void);
673         void         UpdateRouterOnRx(Router &aRouter);
674         void         SendNeighborSolicitToRouter(const Router &aRouter);
675 
676         using SignalTask  = TaskletIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixTableChanged>;
677         using EntryTimer  = TimerMilliIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixTableEntryTimer>;
678         using RouterTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixTableRouterTimer>;
679 
680         Array<Router, kMaxRouters> mRouters;
681         Pool<Entry, kMaxEntries>   mEntryPool;
682         EntryTimer                 mEntryTimer;
683         RouterTimer                mRouterTimer;
684         SignalTask                 mSignalTask;
685     };
686 
687     class OmrPrefixManager;
688 
689     class OmrPrefix : public Clearable<OmrPrefix>
690     {
691         friend class OmrPrefixManager;
692 
693     public:
OmrPrefix(void)694         OmrPrefix(void) { Clear(); }
695 
IsEmpty(void) const696         bool               IsEmpty(void) const { return (mPrefix.GetLength() == 0); }
GetPrefix(void) const697         const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
GetPreference(void) const698         RoutePreference    GetPreference(void) const { return mPreference; }
IsDomainPrefix(void) const699         bool               IsDomainPrefix(void) const { return mIsDomainPrefix; }
700 
701     protected:
702         Ip6::Prefix     mPrefix;
703         RoutePreference mPreference;
704         bool            mIsDomainPrefix;
705     };
706 
707     class FavoredOmrPrefix : public OmrPrefix
708     {
709         friend class OmrPrefixManager;
710 
711     public:
712         bool IsInfrastructureDerived(void) const;
713 
714     private:
715         void SetFrom(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
716         void SetFrom(const OmrPrefix &aOmrPrefix);
717         bool IsFavoredOver(const NetworkData::OnMeshPrefixConfig &aOmrPrefixConfig) const;
718     };
719 
720     class OmrPrefixManager : public InstanceLocator
721     {
722     public:
723         explicit OmrPrefixManager(Instance &aInstance);
724 
725         void                    Init(const Ip6::Prefix &aBrUlaPrefix);
726         void                    Start(void);
727         void                    Stop(void);
728         void                    Evaluate(void);
729         void                    UpdateDefaultRouteFlag(bool aDefaultRoute);
IsLocalAddedInNetData(void) const730         bool                    IsLocalAddedInNetData(void) const { return mIsLocalAddedInNetData; }
GetLocalPrefix(void) const731         const OmrPrefix        &GetLocalPrefix(void) const { return mLocalPrefix; }
GetFavoredPrefix(void) const732         const FavoredOmrPrefix &GetFavoredPrefix(void) const { return mFavoredPrefix; }
733 
734     private:
735         static constexpr uint16_t kInfoStringSize = 85;
736 
737         typedef String<kInfoStringSize> InfoString;
738 
739         void       DetermineFavoredPrefix(void);
740         Error      AddLocalToNetData(void);
741         Error      AddOrUpdateLocalInNetData(void);
742         void       RemoveLocalFromNetData(void);
743         InfoString LocalToString(void) const;
744 
745         OmrPrefix        mLocalPrefix;
746         FavoredOmrPrefix mFavoredPrefix;
747         bool             mIsLocalAddedInNetData;
748         bool             mDefaultRoute;
749     };
750 
HandleOnLinkPrefixManagerTimer(void)751     void HandleOnLinkPrefixManagerTimer(void) { mOnLinkPrefixManager.HandleTimer(); }
752 
753     class OnLinkPrefixManager : public InstanceLocator
754     {
755     public:
756         explicit OnLinkPrefixManager(Instance &aInstance);
757 
758         // Max number of old on-link prefixes to retain to deprecate.
759         static constexpr uint16_t kMaxOldPrefixes = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_OLD_ON_LINK_PREFIXES;
760 
761         void               Init(void);
762         void               Start(void);
763         void               Stop(void);
764         void               Evaluate(void);
GetLocalPrefix(void) const765         const Ip6::Prefix &GetLocalPrefix(void) const { return mLocalPrefix; }
GetFavoredDiscoveredPrefix(void) const766         const Ip6::Prefix &GetFavoredDiscoveredPrefix(void) const { return mFavoredDiscoveredPrefix; }
767         bool               IsInitalEvaluationDone(void) const;
768         void               HandleDiscoveredPrefixTableChanged(void);
769         bool               ShouldPublishUlaRoute(void) const;
770         void               AppendAsPiosTo(Ip6::Nd::RouterAdvertMessage &aRaMessage);
771         bool               IsPublishingOrAdvertising(void) const;
772         void               HandleNetDataChange(void);
773         void               HandleExtPanIdChange(void);
774         void               HandleTimer(void);
775 
776     private:
777         enum State : uint8_t // State of `mLocalPrefix`
778         {
779             kIdle,
780             kPublishing,
781             kAdvertising,
782             kDeprecating,
783         };
784 
785         struct OldPrefix
786         {
Matchesot::BorderRouter::RoutingManager::OnLinkPrefixManager::OldPrefix787             bool Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
788 
789             Ip6::Prefix mPrefix;
790             TimeMilli   mExpireTime;
791         };
792 
793         void GenerateLocalPrefix(void);
794         void PublishAndAdvertise(void);
795         void Deprecate(void);
796         void ResetExpireTime(TimeMilli aNow);
797         void EnterAdvertisingState(void);
798         void AppendCurPrefix(Ip6::Nd::RouterAdvertMessage &aRaMessage);
799         void AppendOldPrefixes(Ip6::Nd::RouterAdvertMessage &aRaMessage);
800         void DeprecateOldPrefix(const Ip6::Prefix &aPrefix, TimeMilli aExpireTime);
801         void SavePrefix(const Ip6::Prefix &aPrefix, TimeMilli aExpireTime);
802 
803         using ExpireTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleOnLinkPrefixManagerTimer>;
804 
805         Ip6::Prefix                       mLocalPrefix;
806         State                             mState;
807         TimeMilli                         mExpireTime;
808         Ip6::Prefix                       mFavoredDiscoveredPrefix;
809         Array<OldPrefix, kMaxOldPrefixes> mOldLocalPrefixes;
810         ExpireTimer                       mTimer;
811     };
812 
813     typedef Ip6::Prefix OnMeshPrefix;
814 
815     class OnMeshPrefixArray : public Array<OnMeshPrefix, kMaxOnMeshPrefixes>
816     {
817     public:
818         void Add(const OnMeshPrefix &aPrefix);
819         void MarkAsDeleted(const OnMeshPrefix &aPrefix);
820     };
821 
822 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
HandleNat64PrefixManagerTimer(void)823     void HandleNat64PrefixManagerTimer(void) { mNat64PrefixManager.HandleTimer(); }
824 
825     class Nat64PrefixManager : public InstanceLocator
826     {
827     public:
828         // This class manages the NAT64 related functions including
829         // generation of local NAT64 prefix, discovery of infra
830         // interface prefix, maintaining the discovered prefix
831         // lifetime, and selection of the NAT64 prefix to publish in
832         // Network Data.
833         //
834         // Calling methods except GenerateLocalPrefix and SetEnabled
835         // when disabled becomes no-op.
836 
837         explicit Nat64PrefixManager(Instance &aInstance);
838 
839         void         SetEnabled(bool aEnabled);
840         Nat64::State GetState(void) const;
841 
842         void Start(void);
843         void Stop(void);
844 
845         void               GenerateLocalPrefix(const Ip6::Prefix &aBrUlaPrefix);
GetLocalPrefix(void) const846         const Ip6::Prefix &GetLocalPrefix(void) const { return mLocalPrefix; }
847         const Ip6::Prefix &GetFavoredPrefix(RoutePreference &aPreference) const;
848         void               Evaluate(void);
849         void               HandleDiscoverDone(const Ip6::Prefix &aPrefix);
850         void               HandleTimer(void);
851 
852     private:
853         void Discover(void);
854         void Publish(void);
855 
856         using Nat64Timer = TimerMilliIn<RoutingManager, &RoutingManager::HandleNat64PrefixManagerTimer>;
857 
858         bool mEnabled;
859 
860         Ip6::Prefix     mInfraIfPrefix;       // The latest NAT64 prefix discovered on the infrastructure interface.
861         Ip6::Prefix     mLocalPrefix;         // The local prefix (from BR ULA prefix).
862         Ip6::Prefix     mPublishedPrefix;     // The prefix to publish in Net Data (empty or local or from infra-if).
863         RoutePreference mPublishedPreference; // The published prefix preference.
864         Nat64Timer      mTimer;
865     };
866 #endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
867 
868     class RoutePublisher : public InstanceLocator // Manages the routes that are published in net data
869     {
870     public:
871         explicit RoutePublisher(Instance &aInstance);
872 
Start(void)873         void Start(void) { Evaluate(); }
Stop(void)874         void Stop(void) { Unpublish(); }
875         void Evaluate(void);
876 
GetPreference(void) const877         RoutePreference GetPreference(void) const { return mPreference; }
878         void            SetPreference(RoutePreference aPreference);
879         void            ClearPreference(void);
880 
881         void HandleRoleChanged(void);
882 
GetUlaPrefix(void)883         static const Ip6::Prefix &GetUlaPrefix(void) { return AsCoreType(&kUlaPrefix); }
884 
885     private:
886         static const otIp6Prefix kUlaPrefix;
887 
888         enum State : uint8_t
889         {
890             kDoNotPublish,   // Do not publish any routes in network data.
891             kPublishDefault, // Publish "::/0" route in network data.
892             kPublishUla,     // Publish "fc00::/7" route in network data.
893         };
894 
895         void DeterminePrefixFor(State aState, Ip6::Prefix &aPrefix) const;
896         void UpdatePublishedRoute(State aNewState);
897         void Unpublish(void);
898         void SetPreferenceBasedOnRole(void);
899         void UpdatePreference(RoutePreference aPreference);
900 
901         static const char *StateToString(State aState);
902 
903         State           mState;
904         RoutePreference mPreference;
905         bool            mUserSetPreference;
906     };
907 
908     struct RaInfo
909     {
910         // Tracks info about emitted RA messages: Number of RAs sent,
911         // last tx time, header to use and whether the header is
912         // discovered from receiving RAs from the host itself. This
913         // ensures that if an entity on host is advertising certain
914         // info in its RA header (e.g., a default route), the RAs we
915         // emit from `RoutingManager` also include the same header.
916 
RaInfoot::BorderRouter::RoutingManager::RaInfo917         RaInfo(void)
918             : mHeaderUpdateTime(TimerMilli::GetNow())
919             , mIsHeaderFromHost(false)
920             , mTxCount(0)
921             , mLastTxTime(TimerMilli::GetNow() - kMinDelayBetweenRtrAdvs)
922         {
923         }
924 
925         Ip6::Nd::RouterAdvertMessage::Header mHeader;
926         TimeMilli                            mHeaderUpdateTime;
927         bool                                 mIsHeaderFromHost;
928         uint32_t                             mTxCount;
929         TimeMilli                            mLastTxTime;
930     };
931 
HandleRsSenderTimer(void)932     void HandleRsSenderTimer(void) { mRsSender.HandleTimer(); }
933 
934     class RsSender : public InstanceLocator
935     {
936     public:
937         // This class implements tx of Router Solicitation (RS)
938         // messages to discover other routers. `Start()` schedules
939         // a cycle of RS transmissions of `kMaxTxCount` separated
940         // by `kTxInterval`. At the end of cycle the callback
941         // `HandleRsSenderFinished()` is invoked to inform end of
942         // the cycle to `RoutingManager`.
943 
944         explicit RsSender(Instance &aInstance);
945 
IsInProgress(void) const946         bool IsInProgress(void) const { return mTimer.IsRunning(); }
947         void Start(void);
948         void Stop(void);
949         void HandleTimer(void);
950 
951     private:
952         // All time intervals are in msec.
953         static constexpr uint32_t kMaxStartDelay     = 1000;        // Max random delay to send the first RS.
954         static constexpr uint32_t kTxInterval        = 4000;        // Interval between RS tx.
955         static constexpr uint32_t kRetryDelay        = kTxInterval; // Interval to wait to retry a failed RS tx.
956         static constexpr uint32_t kWaitOnLastAttempt = 1000;        // Wait interval after last RS tx.
957         static constexpr uint8_t  kMaxTxCount        = 3;           // Number of RS tx in one cycle.
958 
959         Error SendRs(void);
960 
961         using RsTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRsSenderTimer>;
962 
963         uint8_t   mTxCount;
964         RsTimer   mTimer;
965         TimeMilli mStartTime;
966     };
967 
968     void  EvaluateState(void);
969     void  Start(void);
970     void  Stop(void);
971     void  HandleNotifierEvents(Events aEvents);
IsInitialized(void) const972     bool  IsInitialized(void) const { return mInfraIf.IsInitialized(); }
IsEnabled(void) const973     bool  IsEnabled(void) const { return mIsEnabled; }
974     void  SetRioPreferenceBasedOnRole(void);
975     void  UpdateRioPreference(RoutePreference aPreference);
976     Error LoadOrGenerateRandomBrUlaPrefix(void);
977 
978     void EvaluateRoutingPolicy(void);
979     bool IsInitalPolicyEvaluationDone(void) const;
980     void ScheduleRoutingPolicyEvaluation(ScheduleMode aMode);
981     void HandleRsSenderFinished(TimeMilli aStartTime);
982     void SendRouterAdvertisement(RouterAdvTxMode aRaTxMode);
983 
984     void HandleDiscoveredPrefixStaleTimer(void);
985 
986     void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
987     void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
988     void HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket);
989     bool ShouldProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio, const Ip6::Prefix &aPrefix);
990     bool ShouldProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio, const Ip6::Prefix &aPrefix);
991     void UpdateDiscoveredPrefixTableOnNetDataChange(void);
992     bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
993     bool NetworkDataContainsUlaRoute(void) const;
994     void UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage *aRouterAdvertMessage);
995     bool IsReceivedRouterAdvertFromManager(const Ip6::Nd::RouterAdvertMessage &aRaMessage) const;
996     void ResetDiscoveredPrefixStaleTimer(void);
997 
998     static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
999     static bool IsValidOnLinkPrefix(const Ip6::Nd::PrefixInfoOption &aPio);
1000     static bool IsValidOnLinkPrefix(const Ip6::Prefix &aOnLinkPrefix);
1001 
1002     using RoutingPolicyTimer         = TimerMilliIn<RoutingManager, &RoutingManager::EvaluateRoutingPolicy>;
1003     using DiscoveredPrefixStaleTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleDiscoveredPrefixStaleTimer>;
1004 
1005     // Indicates whether the Routing Manager is running (started).
1006     bool mIsRunning;
1007 
1008     // Indicates whether the Routing manager is enabled. The Routing
1009     // Manager will be stopped if we are disabled.
1010     bool mIsEnabled;
1011 
1012     InfraIf mInfraIf;
1013 
1014     // The /48 BR ULA prefix loaded from local persistent storage or
1015     // randomly generated if none is found in persistent storage.
1016     Ip6::Prefix mBrUlaPrefix;
1017 
1018     OmrPrefixManager mOmrPrefixManager;
1019 
1020     // List of on-mesh prefixes (discovered from Network Data) which
1021     // were advertised as RIO in the last sent RA message.
1022     OnMeshPrefixArray mAdvertisedPrefixes;
1023 
1024     RoutePreference mRioPreference;
1025     bool            mUserSetRioPreference;
1026 
1027     OnLinkPrefixManager mOnLinkPrefixManager;
1028 
1029     DiscoveredPrefixTable mDiscoveredPrefixTable;
1030 
1031     RoutePublisher mRoutePublisher;
1032 
1033 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
1034     Nat64PrefixManager mNat64PrefixManager;
1035 #endif
1036 
1037     RaInfo   mRaInfo;
1038     RsSender mRsSender;
1039 
1040     DiscoveredPrefixStaleTimer mDiscoveredPrefixStaleTimer;
1041     RoutingPolicyTimer         mRoutingPolicyTimer;
1042 };
1043 
1044 } // namespace BorderRouter
1045 
1046 DefineMapEnum(otBorderRoutingState, BorderRouter::RoutingManager::State);
1047 
1048 } // namespace ot
1049 
1050 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
1051 
1052 #endif // ROUTING_MANAGER_HPP_
1053