xref: /aosp_15_r20/external/openthread/tests/unit/test_routing_manager.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2022, 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 #include <openthread/config.h>
30 
31 #include "test_platform.h"
32 #include "test_util.hpp"
33 
34 #include <openthread/dataset_ftd.h>
35 #include <openthread/thread.h>
36 #include <openthread/platform/border_routing.h>
37 
38 #include "border_router/routing_manager.hpp"
39 #include "common/arg_macros.hpp"
40 #include "common/array.hpp"
41 #include "common/numeric_limits.hpp"
42 #include "common/time.hpp"
43 #include "instance/instance.hpp"
44 #include "net/icmp6.hpp"
45 #include "net/nd6.hpp"
46 
47 namespace ot {
48 
49 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
50 
51 // Logs a message and adds current time (sNow) as "<hours>:<min>:<secs>.<msec>"
52 #define Log(...)                                                                                         \
53     printf("%02u:%02u:%02u.%03u " OT_FIRST_ARG(__VA_ARGS__) "\n", (sNow / 3600000), (sNow / 60000) % 60, \
54            (sNow / 1000) % 60, sNow % 1000 OT_REST_ARGS(__VA_ARGS__))
55 
56 static constexpr uint32_t kInfraIfIndex     = 1;
57 static const char         kInfraIfAddress[] = "fe80::1";
58 
59 static constexpr uint32_t kValidLitime       = 2000;
60 static constexpr uint32_t kPreferredLifetime = 1800;
61 static constexpr uint32_t kInfiniteLifetime  = NumericLimits<uint32_t>::kMax;
62 
63 static constexpr uint32_t kRioValidLifetime       = 1800;
64 static constexpr uint32_t kRioDeprecatingLifetime = 300;
65 
66 static constexpr uint16_t kMaxRaSize              = 800;
67 static constexpr uint16_t kMaxDeprecatingPrefixes = 16;
68 
69 static constexpr otOperationalDataset kDataset = {
70     .mActiveTimestamp =
71         {
72             .mSeconds       = 1,
73             .mTicks         = 0,
74             .mAuthoritative = false,
75         },
76     .mNetworkKey =
77         {
78             .m8 = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
79         },
80     .mNetworkName = {"OpenThread"},
81     .mExtendedPanId =
82         {
83             .m8 = {0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0xca, 0xfe},
84         },
85     .mMeshLocalPrefix =
86         {
87             .m8 = {0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
88         },
89     .mPanId   = 0x1234,
90     .mChannel = 11,
91     .mPskc =
92         {
93             .m8 = {0xc2, 0x3a, 0x76, 0xe9, 0x8f, 0x1a, 0x64, 0x83, 0x63, 0x9b, 0x1a, 0xc1, 0x27, 0x1e, 0x2e, 0x27},
94         },
95     .mSecurityPolicy =
96         {
97             .mRotationTime                 = 672,
98             .mObtainNetworkKeyEnabled      = true,
99             .mNativeCommissioningEnabled   = true,
100             .mRoutersEnabled               = true,
101             .mExternalCommissioningEnabled = true,
102         },
103     .mChannelMask = 0x07fff800,
104     .mComponents =
105         {
106             .mIsActiveTimestampPresent = true,
107             .mIsNetworkKeyPresent      = true,
108             .mIsNetworkNamePresent     = true,
109             .mIsExtendedPanIdPresent   = true,
110             .mIsMeshLocalPrefixPresent = true,
111             .mIsPanIdPresent           = true,
112             .mIsChannelPresent         = true,
113             .mIsPskcPresent            = true,
114             .mIsSecurityPolicyPresent  = true,
115             .mIsChannelMaskPresent     = true,
116         },
117 };
118 
119 static Instance *sInstance;
120 
121 static uint32_t sNow = 0;
122 static uint32_t sAlarmTime;
123 static bool     sAlarmOn = false;
124 
125 static otRadioFrame sRadioTxFrame;
126 static uint8_t      sRadioTxFramePsdu[OT_RADIO_FRAME_MAX_SIZE];
127 static bool         sRadioTxOngoing = false;
128 
129 using Icmp6Packet = Ip6::Nd::RouterAdvert::Icmp6Packet;
130 
131 enum ExpectedPio
132 {
133     kNoPio,                     // Expect to see no PIO in RA.
134     kPioAdvertisingLocalOnLink, // Expect to see local on-link prefix advertised (non-zero preferred lifetime).
135     kPioDeprecatingLocalOnLink, // Expect to see local on-link prefix deprecated (zero preferred lifetime).
136 };
137 
138 struct DeprecatingPrefix
139 {
140     DeprecatingPrefix(void) = default;
141 
DeprecatingPrefixot::DeprecatingPrefix142     DeprecatingPrefix(const Ip6::Prefix &aPrefix, uint32_t aLifetime)
143         : mPrefix(aPrefix)
144         , mLifetime(aLifetime)
145     {
146     }
147 
Matchesot::DeprecatingPrefix148     bool Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
149 
150     Ip6::Prefix mPrefix;   // Old on-link prefix being deprecated.
151     uint32_t    mLifetime; // Valid lifetime of prefix from PIO.
152 };
153 
154 static Ip6::Address sInfraIfAddress;
155 
156 bool        sRsEmitted;      // Indicates if an RS message was emitted by BR.
157 bool        sRaValidated;    // Indicates if an RA was emitted by BR and successfully validated.
158 bool        sNsEmitted;      // Indicates if an NS message was emitted by BR.
159 bool        sRespondToNs;    // Indicates whether or not to respond to NS.
160 ExpectedPio sExpectedPio;    // Expected PIO in the emitted RA by BR (MUST be seen in RA to set `sRaValidated`).
161 uint32_t    sOnLinkLifetime; // Valid lifetime for local on-link prefix from the last processed RA.
162 
163 // Indicate whether or not to check the emitted RA header (default route) lifetime
164 bool sCheckRaHeaderLifetime;
165 
166 // Expected default route lifetime in emitted RA header by BR.
167 uint32_t sExpectedRaHeaderLifetime;
168 
169 enum ExpectedRaHeaderFlags
170 {
171     kRaHeaderFlagsSkipChecking, // Skip checking the RA header flags.
172     kRaHeaderFlagsNone,         // Expect no flag (neither M or O).
173     kRaHeaderFlagsOnlyM,        // Expect M flag only.
174     kRaHeaderFlagsOnlyO,        // Expect O flag only.
175     kRaHeaderFlagsBothMAndO,    // Expect both M and O flags.
176 };
177 
178 // The expected RA header flags when validating emitted RA message.
179 ExpectedRaHeaderFlags sExpectedRaHeaderFlags;
180 
181 // Array containing deprecating prefixes from PIOs in the last processed RA.
182 Array<DeprecatingPrefix, kMaxDeprecatingPrefixes> sDeprecatingPrefixes;
183 
184 static constexpr uint16_t kMaxRioPrefixes = 10;
185 
186 using NetworkData::RoutePreference;
187 
188 struct RioPrefix
189 {
190     RioPrefix(void) = default;
191 
RioPrefixot::RioPrefix192     explicit RioPrefix(const Ip6::Prefix &aPrefix)
193         : mSawInRa(false)
194         , mPrefix(aPrefix)
195         , mLifetime(0)
196         , mPreference(NetworkData::kRoutePreferenceMedium)
197     {
198     }
199 
200     bool            mSawInRa;    // Indicate whether or not this prefix was seen in the emitted RA (as RIO).
201     Ip6::Prefix     mPrefix;     // The RIO prefix.
202     uint32_t        mLifetime;   // The RIO prefix lifetime - only valid when `mSawInRa`
203     RoutePreference mPreference; // The RIO preference - only valid when `mSawInRa`
204 };
205 
206 class ExpectedRios : public Array<RioPrefix, kMaxRioPrefixes>
207 {
208 public:
Add(const Ip6::Prefix & aPrefix)209     void Add(const Ip6::Prefix &aPrefix) { SuccessOrQuit(PushBack(RioPrefix(aPrefix))); }
210 
SawAll(void) const211     bool SawAll(void) const
212     {
213         bool sawAll = true;
214 
215         for (const RioPrefix &rioPrefix : *this)
216         {
217             if (!rioPrefix.mSawInRa)
218             {
219                 sawAll = false;
220                 break;
221             }
222         }
223 
224         return sawAll;
225     }
226 };
227 
228 ExpectedRios sExpectedRios; // Expected RIO prefixes in emitted RAs.
229 
230 //----------------------------------------------------------------------------------------------------------------------
231 // Function prototypes
232 
233 void        ProcessRadioTxAndTasklets(void);
234 void        AdvanceTime(uint32_t aDuration);
235 void        LogRouterAdvert(const Icmp6Packet &aPacket);
236 void        ValidateRouterAdvert(const Icmp6Packet &aPacket);
237 const char *PreferenceToString(int8_t aPreference);
238 void        SendRouterAdvert(const Ip6::Address &aAddress, const Icmp6Packet &aPacket);
239 void        SendNeighborAdvert(const Ip6::Address &aAddress, const Ip6::Nd::NeighborAdvertMessage &aNaMessage);
240 void        DiscoverNat64Prefix(const Ip6::Prefix &aPrefix);
241 
242 extern "C" {
243 
244 #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)245 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
246 {
247     OT_UNUSED_VARIABLE(aLogLevel);
248     OT_UNUSED_VARIABLE(aLogRegion);
249 
250     va_list args;
251 
252     printf("   ");
253     va_start(args, aFormat);
254     vprintf(aFormat, args);
255     va_end(args);
256     printf("\n");
257 }
258 #endif
259 
260 //----------------------------------------------------------------------------------------------------------------------
261 // `otPlatRadio
262 
otPlatRadioGetCaps(otInstance *)263 otRadioCaps otPlatRadioGetCaps(otInstance *) { return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF; }
264 
otPlatRadioTransmit(otInstance *,otRadioFrame *)265 otError otPlatRadioTransmit(otInstance *, otRadioFrame *)
266 {
267     sRadioTxOngoing = true;
268 
269     return OT_ERROR_NONE;
270 }
271 
otPlatRadioGetTransmitBuffer(otInstance *)272 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *) { return &sRadioTxFrame; }
273 
274 //----------------------------------------------------------------------------------------------------------------------
275 // `otPlatAlaram
276 
otPlatAlarmMilliStop(otInstance *)277 void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
278 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)279 void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
280 {
281     sAlarmOn   = true;
282     sAlarmTime = aT0 + aDt;
283 }
284 
otPlatAlarmMilliGetNow(void)285 uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
286 
287 //---------------------------------------------------------------------------------------------------------------------
288 // otPlatInfraIf
289 
otPlatInfraIfHasAddress(uint32_t aInfraIfIndex,const otIp6Address * aAddress)290 bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress)
291 {
292     VerifyOrQuit(aInfraIfIndex == kInfraIfIndex);
293 
294     return AsCoreType(aAddress) == sInfraIfAddress;
295 }
296 
otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,const otIp6Address * aDestAddress,const uint8_t * aBuffer,uint16_t aBufferLength)297 otError otPlatInfraIfSendIcmp6Nd(uint32_t            aInfraIfIndex,
298                                  const otIp6Address *aDestAddress,
299                                  const uint8_t      *aBuffer,
300                                  uint16_t            aBufferLength)
301 {
302     Icmp6Packet        packet;
303     Ip6::Icmp::Header *header;
304 
305     Log("otPlatInfraIfSendIcmp6Nd(aDestAddr: %s, aBufferLength:%u)", AsCoreType(aDestAddress).ToString().AsCString(),
306         aBufferLength);
307 
308     VerifyOrQuit(aInfraIfIndex == kInfraIfIndex);
309 
310     packet.Init(aBuffer, aBufferLength);
311 
312     VerifyOrQuit(aBufferLength >= sizeof(Ip6::Icmp::Header));
313 
314     header = reinterpret_cast<Ip6::Icmp::Header *>(const_cast<uint8_t *>(aBuffer));
315 
316     switch (header->GetType())
317     {
318     case Ip6::Icmp::Header::kTypeRouterSolicit:
319         Log("  Router Solicit message");
320         sRsEmitted = true;
321         break;
322 
323     case Ip6::Icmp::Header::kTypeRouterAdvert:
324         Log("  Router Advertisement message");
325         LogRouterAdvert(packet);
326         ValidateRouterAdvert(packet);
327         // Intentionally modify the checksum field in RA Header
328         // before passing it back to the OT stack.
329         header->SetChecksum(0x1234);
330         otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &sInfraIfAddress, aBuffer, aBufferLength);
331         break;
332 
333     case Ip6::Icmp::Header::kTypeNeighborSolicit:
334     {
335         const Ip6::Nd::NeighborSolicitMessage *nsMsg =
336             reinterpret_cast<const Ip6::Nd::NeighborSolicitMessage *>(packet.GetBytes());
337 
338         Log("  Neighbor Solicit message");
339 
340         VerifyOrQuit(packet.GetLength() >= sizeof(Ip6::Nd::NeighborSolicitMessage));
341         VerifyOrQuit(nsMsg->IsValid());
342         sNsEmitted = true;
343 
344         if (sRespondToNs)
345         {
346             Ip6::Nd::NeighborAdvertMessage naMsg;
347 
348             naMsg.SetTargetAddress(nsMsg->GetTargetAddress());
349             naMsg.SetRouterFlag();
350             naMsg.SetSolicitedFlag();
351             SendNeighborAdvert(AsCoreType(aDestAddress), naMsg);
352         }
353 
354         break;
355     }
356 
357     default:
358         VerifyOrQuit(false, "Bad ICMP6 type");
359     }
360 
361     return OT_ERROR_NONE;
362 }
363 
364 //----------------------------------------------------------------------------------------------------------------------
365 
366 Array<void *, 500> sHeapAllocatedPtrs;
367 
368 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
369 
otPlatCAlloc(size_t aNum,size_t aSize)370 void *otPlatCAlloc(size_t aNum, size_t aSize)
371 {
372     void *ptr = calloc(aNum, aSize);
373 
374     SuccessOrQuit(sHeapAllocatedPtrs.PushBack(ptr));
375 
376     return ptr;
377 }
378 
otPlatFree(void * aPtr)379 void otPlatFree(void *aPtr)
380 {
381     if (aPtr != nullptr)
382     {
383         void **entry = sHeapAllocatedPtrs.Find(aPtr);
384 
385         VerifyOrQuit(entry != nullptr, "A heap allocated item is freed twice");
386         sHeapAllocatedPtrs.Remove(*entry);
387     }
388 
389     free(aPtr);
390 }
391 
392 #endif
393 
394 } // extern "C"
395 
396 //---------------------------------------------------------------------------------------------------------------------
397 
ProcessRadioTxAndTasklets(void)398 void ProcessRadioTxAndTasklets(void)
399 {
400     do
401     {
402         if (sRadioTxOngoing)
403         {
404             sRadioTxOngoing = false;
405             otPlatRadioTxStarted(sInstance, &sRadioTxFrame);
406             otPlatRadioTxDone(sInstance, &sRadioTxFrame, nullptr, OT_ERROR_NONE);
407         }
408 
409         otTaskletsProcess(sInstance);
410     } while (otTaskletsArePending(sInstance));
411 }
412 
AdvanceTime(uint32_t aDuration)413 void AdvanceTime(uint32_t aDuration)
414 {
415     uint32_t time = sNow + aDuration;
416 
417     Log("AdvanceTime for %u.%03u", aDuration / 1000, aDuration % 1000);
418 
419     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
420     {
421         ProcessRadioTxAndTasklets();
422         sNow = sAlarmTime;
423         otPlatAlarmMilliFired(sInstance);
424     }
425 
426     ProcessRadioTxAndTasklets();
427     sNow = time;
428 }
429 
ValidateRouterAdvert(const Icmp6Packet & aPacket)430 void ValidateRouterAdvert(const Icmp6Packet &aPacket)
431 {
432     constexpr uint8_t kMaxPrefixes = 16;
433 
434     Ip6::Nd::RouterAdvert::RxMessage raMsg(aPacket);
435     bool                             sawExpectedPio = false;
436     Array<Ip6::Prefix, kMaxPrefixes> pioPrefixes;
437     Array<Ip6::Prefix, kMaxPrefixes> rioPrefixes;
438 #if OPENTHREAD_CONFIG_BORDER_ROUTING_STUB_ROUTER_FLAG_IN_EMITTED_RA_ENABLE
439     bool sawStubRouterFlag = false;
440 #endif
441 
442     VerifyOrQuit(raMsg.IsValid());
443 
444     if (sCheckRaHeaderLifetime)
445     {
446         VerifyOrQuit(raMsg.GetHeader().GetRouterLifetime() == sExpectedRaHeaderLifetime);
447     }
448 
449     switch (sExpectedRaHeaderFlags)
450     {
451     case kRaHeaderFlagsSkipChecking:
452         break;
453     case kRaHeaderFlagsNone:
454         VerifyOrQuit(!raMsg.GetHeader().IsManagedAddressConfigFlagSet());
455         VerifyOrQuit(!raMsg.GetHeader().IsOtherConfigFlagSet());
456         break;
457     case kRaHeaderFlagsOnlyM:
458         VerifyOrQuit(raMsg.GetHeader().IsManagedAddressConfigFlagSet());
459         VerifyOrQuit(!raMsg.GetHeader().IsOtherConfigFlagSet());
460         break;
461     case kRaHeaderFlagsOnlyO:
462         VerifyOrQuit(!raMsg.GetHeader().IsManagedAddressConfigFlagSet());
463         VerifyOrQuit(raMsg.GetHeader().IsOtherConfigFlagSet());
464         break;
465     case kRaHeaderFlagsBothMAndO:
466         VerifyOrQuit(raMsg.GetHeader().IsManagedAddressConfigFlagSet());
467         VerifyOrQuit(raMsg.GetHeader().IsOtherConfigFlagSet());
468         break;
469     }
470 
471     sDeprecatingPrefixes.Clear();
472 
473     for (const Ip6::Nd::Option &option : raMsg)
474     {
475         switch (option.GetType())
476         {
477         case Ip6::Nd::Option::kTypePrefixInfo:
478         {
479             const Ip6::Nd::PrefixInfoOption &pio = static_cast<const Ip6::Nd::PrefixInfoOption &>(option);
480             Ip6::Prefix                      prefix;
481             Ip6::Prefix                      localOnLink;
482 
483             VerifyOrQuit(pio.IsValid());
484             pio.GetPrefix(prefix);
485 
486             VerifyOrQuit(!pioPrefixes.Contains(prefix), "Duplicate PIO prefix in RA");
487             SuccessOrQuit(pioPrefixes.PushBack(prefix));
488 
489             SuccessOrQuit(otBorderRoutingGetOnLinkPrefix(sInstance, &localOnLink));
490 
491             if (prefix == localOnLink)
492             {
493                 switch (sExpectedPio)
494                 {
495                 case kNoPio:
496                     break;
497 
498                 case kPioAdvertisingLocalOnLink:
499                     if (pio.GetPreferredLifetime() > 0)
500                     {
501                         sOnLinkLifetime = pio.GetValidLifetime();
502                         sawExpectedPio  = true;
503                     }
504                     break;
505 
506                 case kPioDeprecatingLocalOnLink:
507                     if (pio.GetPreferredLifetime() == 0)
508                     {
509                         sOnLinkLifetime = pio.GetValidLifetime();
510                         sawExpectedPio  = true;
511                     }
512                     break;
513                 }
514             }
515             else
516             {
517                 VerifyOrQuit(pio.GetPreferredLifetime() == 0, "Old on link prefix is not deprecated");
518                 SuccessOrQuit(sDeprecatingPrefixes.PushBack(DeprecatingPrefix(prefix, pio.GetValidLifetime())));
519             }
520             break;
521         }
522 
523         case Ip6::Nd::Option::kTypeRouteInfo:
524         {
525             const Ip6::Nd::RouteInfoOption &rio = static_cast<const Ip6::Nd::RouteInfoOption &>(option);
526             Ip6::Prefix                     prefix;
527 
528             VerifyOrQuit(rio.IsValid());
529             rio.GetPrefix(prefix);
530 
531             VerifyOrQuit(!rioPrefixes.Contains(prefix), "Duplicate RIO prefix in RA");
532             SuccessOrQuit(rioPrefixes.PushBack(prefix));
533 
534             for (RioPrefix &rioPrefix : sExpectedRios)
535             {
536                 if (prefix == rioPrefix.mPrefix)
537                 {
538                     rioPrefix.mSawInRa    = true;
539                     rioPrefix.mLifetime   = rio.GetRouteLifetime();
540                     rioPrefix.mPreference = rio.GetPreference();
541                 }
542             }
543 
544             break;
545         }
546 
547 #if OPENTHREAD_CONFIG_BORDER_ROUTING_STUB_ROUTER_FLAG_IN_EMITTED_RA_ENABLE
548         case Ip6::Nd::Option::kTypeRaFlagsExtension:
549         {
550             const Ip6::Nd::RaFlagsExtOption &flagsOption = static_cast<const Ip6::Nd::RaFlagsExtOption &>(option);
551 
552             VerifyOrQuit(flagsOption.IsValid());
553             VerifyOrQuit(flagsOption.IsStubRouterFlagSet());
554             sawStubRouterFlag = true;
555             break;
556         }
557 #endif
558 
559         default:
560             VerifyOrQuit(false, "Unexpected option type in RA msg");
561         }
562     }
563 
564 #if OPENTHREAD_CONFIG_BORDER_ROUTING_STUB_ROUTER_FLAG_IN_EMITTED_RA_ENABLE
565     VerifyOrQuit(sawStubRouterFlag);
566 #endif
567 
568     if (!sRaValidated)
569     {
570         switch (sExpectedPio)
571         {
572         case kNoPio:
573             break;
574         case kPioAdvertisingLocalOnLink:
575         case kPioDeprecatingLocalOnLink:
576             // First emitted RAs may not yet have the expected PIO
577             // so we exit and not set `sRaValidated` to allow it
578             // to be checked for next received RA.
579             VerifyOrExit(sawExpectedPio);
580             break;
581         }
582 
583         sRaValidated = true;
584     }
585 
586 exit:
587     return;
588 }
589 
590 //----------------------------------------------------------------------------------------------------------------------
591 
LogRouterAdvert(const Icmp6Packet & aPacket)592 void LogRouterAdvert(const Icmp6Packet &aPacket)
593 {
594     Ip6::Nd::RouterAdvert::RxMessage raMsg(aPacket);
595 
596     VerifyOrQuit(raMsg.IsValid());
597 
598     Log("     RA header - M:%u, O:%u", raMsg.GetHeader().IsManagedAddressConfigFlagSet(),
599         raMsg.GetHeader().IsOtherConfigFlagSet());
600     Log("     RA header - lifetime %u, prf:%s", raMsg.GetHeader().GetRouterLifetime(),
601         PreferenceToString(raMsg.GetHeader().GetDefaultRouterPreference()));
602 
603     for (const Ip6::Nd::Option &option : raMsg)
604     {
605         switch (option.GetType())
606         {
607         case Ip6::Nd::Option::kTypePrefixInfo:
608         {
609             const Ip6::Nd::PrefixInfoOption &pio = static_cast<const Ip6::Nd::PrefixInfoOption &>(option);
610             Ip6::Prefix                      prefix;
611 
612             VerifyOrQuit(pio.IsValid());
613             pio.GetPrefix(prefix);
614             Log("     PIO - %s, flags:%s%s, valid:%u, preferred:%u", prefix.ToString().AsCString(),
615                 pio.IsOnLinkFlagSet() ? "L" : "", pio.IsAutoAddrConfigFlagSet() ? "A" : "", pio.GetValidLifetime(),
616                 pio.GetPreferredLifetime());
617             break;
618         }
619 
620         case Ip6::Nd::Option::kTypeRouteInfo:
621         {
622             const Ip6::Nd::RouteInfoOption &rio = static_cast<const Ip6::Nd::RouteInfoOption &>(option);
623             Ip6::Prefix                     prefix;
624 
625             VerifyOrQuit(rio.IsValid());
626             rio.GetPrefix(prefix);
627             Log("     RIO - %s, prf:%s, lifetime:%u", prefix.ToString().AsCString(),
628                 PreferenceToString(rio.GetPreference()), rio.GetRouteLifetime());
629             break;
630         }
631 
632         case Ip6::Nd::Option::kTypeRaFlagsExtension:
633         {
634             const Ip6::Nd::RaFlagsExtOption &flagsOption = static_cast<const Ip6::Nd::RaFlagsExtOption &>(option);
635 
636             VerifyOrQuit(flagsOption.IsValid());
637             Log("     FlagsExt - StubRouter:%u", flagsOption.IsStubRouterFlagSet());
638             break;
639         }
640 
641         default:
642             VerifyOrQuit(false, "Bad option type in RA msg");
643         }
644     }
645 }
646 
LogRouterAdvert(const uint8_t * aBuffer,size_t aLength)647 void LogRouterAdvert(const uint8_t *aBuffer, size_t aLength)
648 {
649     Icmp6Packet packet;
650     packet.Init(aBuffer, aLength);
651     LogRouterAdvert(packet);
652 }
653 
PreferenceToString(int8_t aPreference)654 const char *PreferenceToString(int8_t aPreference)
655 {
656     const char *str = "";
657 
658     switch (aPreference)
659     {
660     case NetworkData::kRoutePreferenceLow:
661         str = "low";
662         break;
663 
664     case NetworkData::kRoutePreferenceMedium:
665         str = "med";
666         break;
667 
668     case NetworkData::kRoutePreferenceHigh:
669         str = "high";
670         break;
671 
672     default:
673         break;
674     }
675 
676     return str;
677 }
678 
SendRouterAdvert(const Ip6::Address & aAddress,const uint8_t * aBuffer,uint16_t aLength)679 void SendRouterAdvert(const Ip6::Address &aAddress, const uint8_t *aBuffer, uint16_t aLength)
680 {
681     otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &aAddress, aBuffer, aLength);
682 }
683 
SendRouterAdvert(const Ip6::Address & aAddress,const Icmp6Packet & aPacket)684 void SendRouterAdvert(const Ip6::Address &aAddress, const Icmp6Packet &aPacket)
685 {
686     SendRouterAdvert(aAddress, aPacket.GetBytes(), aPacket.GetLength());
687 }
688 
SendNeighborAdvert(const Ip6::Address & aAddress,const Ip6::Nd::NeighborAdvertMessage & aNaMessage)689 void SendNeighborAdvert(const Ip6::Address &aAddress, const Ip6::Nd::NeighborAdvertMessage &aNaMessage)
690 {
691     Log("Sending NA from %s", aAddress.ToString().AsCString());
692     otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &aAddress, reinterpret_cast<const uint8_t *>(&aNaMessage),
693                              sizeof(aNaMessage));
694 }
695 
DiscoverNat64Prefix(const Ip6::Prefix & aPrefix)696 void DiscoverNat64Prefix(const Ip6::Prefix &aPrefix)
697 {
698     Log("Discovered NAT64 prefix %s", aPrefix.ToString().AsCString());
699 
700     otPlatInfraIfDiscoverNat64PrefixDone(sInstance, kInfraIfIndex, &aPrefix);
701 }
702 
PrefixFromString(const char * aString,uint8_t aPrefixLength)703 Ip6::Prefix PrefixFromString(const char *aString, uint8_t aPrefixLength)
704 {
705     Ip6::Prefix prefix;
706 
707     SuccessOrQuit(AsCoreType(&prefix.mPrefix).FromString(aString));
708     prefix.mLength = aPrefixLength;
709 
710     return prefix;
711 }
712 
AddressFromString(const char * aString)713 Ip6::Address AddressFromString(const char *aString)
714 {
715     Ip6::Address address;
716 
717     SuccessOrQuit(address.FromString(aString));
718 
719     return address;
720 }
721 
VerifyOmrPrefixInNetData(const Ip6::Prefix & aOmrPrefix,bool aDefaultRoute)722 void VerifyOmrPrefixInNetData(const Ip6::Prefix &aOmrPrefix, bool aDefaultRoute)
723 {
724     otNetworkDataIterator           iterator = OT_NETWORK_DATA_ITERATOR_INIT;
725     NetworkData::OnMeshPrefixConfig prefixConfig;
726 
727     Log("VerifyOmrPrefixInNetData(%s, def-route:%s)", aOmrPrefix.ToString().AsCString(), aDefaultRoute ? "yes" : "no");
728 
729     SuccessOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig));
730     VerifyOrQuit(prefixConfig.GetPrefix() == aOmrPrefix);
731     VerifyOrQuit(prefixConfig.mStable == true);
732     VerifyOrQuit(prefixConfig.mSlaac == true);
733     VerifyOrQuit(prefixConfig.mPreferred == true);
734     VerifyOrQuit(prefixConfig.mOnMesh == true);
735     VerifyOrQuit(prefixConfig.mDefaultRoute == aDefaultRoute);
736 
737     VerifyOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig) == kErrorNotFound);
738 }
739 
VerifyNoOmrPrefixInNetData(void)740 void VerifyNoOmrPrefixInNetData(void)
741 {
742     otNetworkDataIterator           iterator = OT_NETWORK_DATA_ITERATOR_INIT;
743     NetworkData::OnMeshPrefixConfig prefixConfig;
744 
745     Log("VerifyNoOmrPrefixInNetData()");
746     VerifyOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig) != kErrorNone);
747 }
748 
749 enum ExternalRouteMode : uint8_t
750 {
751     kNoRoute,
752     kDefaultRoute,
753     kUlaRoute,
754 };
755 
756 enum AdvPioMode : uint8_t
757 {
758     kSkipAdvPioCheck,
759     kWithAdvPioFlagSet,
760     kWithAdvPioCleared,
761 };
762 
VerifyExternalRouteInNetData(ExternalRouteMode aExternalRouteMode,AdvPioMode aAdvPioMode=kSkipAdvPioCheck)763 void VerifyExternalRouteInNetData(ExternalRouteMode aExternalRouteMode, AdvPioMode aAdvPioMode = kSkipAdvPioCheck)
764 {
765     Error                 error;
766     otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
767     otExternalRouteConfig routeConfig;
768 
769     error = otNetDataGetNextRoute(sInstance, &iterator, &routeConfig);
770 
771     switch (aExternalRouteMode)
772     {
773     case kNoRoute:
774         Log("VerifyExternalRouteInNetData(kNoRoute)");
775         VerifyOrQuit(error != kErrorNone);
776         break;
777 
778     case kDefaultRoute:
779         Log("VerifyExternalRouteInNetData(kDefaultRoute)");
780         VerifyOrQuit(error == kErrorNone);
781         VerifyOrQuit(routeConfig.mPrefix.mLength == 0);
782         VerifyOrQuit((aAdvPioMode == kSkipAdvPioCheck) || (routeConfig.mAdvPio == (aAdvPioMode == kWithAdvPioFlagSet)));
783         VerifyOrQuit(otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) != kErrorNone);
784         break;
785 
786     case kUlaRoute:
787         Log("VerifyExternalRouteInNetData(kUlaRoute)");
788         VerifyOrQuit(error == kErrorNone);
789         VerifyOrQuit(routeConfig.mPrefix.mLength == 7);
790         VerifyOrQuit(routeConfig.mPrefix.mPrefix.mFields.m8[0] == 0xfc);
791         VerifyOrQuit((aAdvPioMode == kSkipAdvPioCheck) || (routeConfig.mAdvPio == (aAdvPioMode == kWithAdvPioFlagSet)));
792         VerifyOrQuit(otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) != kErrorNone);
793         break;
794     }
795 }
796 
VerifyNat64PrefixInNetData(const Ip6::Prefix & aNat64Prefix)797 void VerifyNat64PrefixInNetData(const Ip6::Prefix &aNat64Prefix)
798 {
799     otNetworkDataIterator            iterator = OT_NETWORK_DATA_ITERATOR_INIT;
800     NetworkData::ExternalRouteConfig routeConfig;
801     bool                             didFind = false;
802 
803     Log("VerifyNat64PrefixInNetData()");
804 
805     while (otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) == kErrorNone)
806     {
807         if (!routeConfig.mNat64 || !routeConfig.GetPrefix().IsValidNat64())
808         {
809             continue;
810         }
811 
812         Log("   nat64 prefix:%s, prf:%s", routeConfig.GetPrefix().ToString().AsCString(),
813             PreferenceToString(routeConfig.mPreference));
814 
815         VerifyOrQuit(routeConfig.GetPrefix() == aNat64Prefix);
816         didFind = true;
817     }
818 
819     VerifyOrQuit(didFind);
820 }
821 
822 struct Pio
823 {
Pioot::Pio824     Pio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime)
825         : mPrefix(aPrefix)
826         , mValidLifetime(aValidLifetime)
827         , mPreferredLifetime(aPreferredLifetime)
828     {
829     }
830 
831     const Ip6::Prefix &mPrefix;
832     uint32_t           mValidLifetime;
833     uint32_t           mPreferredLifetime;
834 };
835 
836 struct Rio
837 {
Rioot::Rio838     Rio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, RoutePreference aPreference)
839         : mPrefix(aPrefix)
840         , mValidLifetime(aValidLifetime)
841         , mPreference(aPreference)
842     {
843     }
844 
845     const Ip6::Prefix &mPrefix;
846     uint32_t           mValidLifetime;
847     RoutePreference    mPreference;
848 };
849 
850 struct DefaultRoute
851 {
DefaultRouteot::DefaultRoute852     DefaultRoute(uint32_t aLifetime, RoutePreference aPreference)
853         : mLifetime(aLifetime)
854         , mPreference(aPreference)
855     {
856     }
857 
858     uint32_t        mLifetime;
859     RoutePreference mPreference;
860 };
861 
862 struct RaFlags : public Clearable<RaFlags>
863 {
RaFlagsot::RaFlags864     RaFlags(void)
865         : mManagedAddressConfigFlag(false)
866         , mOtherConfigFlag(false)
867         , mStubRouterFlag(false)
868     {
869     }
870 
871     bool mManagedAddressConfigFlag;
872     bool mOtherConfigFlag;
873     bool mStubRouterFlag;
874 };
875 
BuildRouterAdvert(Ip6::Nd::RouterAdvert::TxMessage & aRaMsg,const Pio * aPios,uint16_t aNumPios,const Rio * aRios,uint16_t aNumRios,const DefaultRoute & aDefaultRoute,const RaFlags & aRaFlags)876 void BuildRouterAdvert(Ip6::Nd::RouterAdvert::TxMessage &aRaMsg,
877                        const Pio                        *aPios,
878                        uint16_t                          aNumPios,
879                        const Rio                        *aRios,
880                        uint16_t                          aNumRios,
881                        const DefaultRoute               &aDefaultRoute,
882                        const RaFlags                    &aRaFlags)
883 {
884     Ip6::Nd::RouterAdvert::Header header;
885 
886     header.SetRouterLifetime(aDefaultRoute.mLifetime);
887     header.SetDefaultRouterPreference(aDefaultRoute.mPreference);
888 
889     if (aRaFlags.mManagedAddressConfigFlag)
890     {
891         header.SetManagedAddressConfigFlag();
892     }
893 
894     if (aRaFlags.mOtherConfigFlag)
895     {
896         header.SetOtherConfigFlag();
897     }
898 
899     SuccessOrQuit(aRaMsg.AppendHeader(header));
900 
901     if (aRaFlags.mStubRouterFlag)
902     {
903         SuccessOrQuit(aRaMsg.AppendFlagsExtensionOption(/* aStubRouterFlag */ true));
904     }
905 
906     for (; aNumPios > 0; aPios++, aNumPios--)
907     {
908         SuccessOrQuit(aRaMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime));
909     }
910 
911     for (; aNumRios > 0; aRios++, aNumRios--)
912     {
913         SuccessOrQuit(aRaMsg.AppendRouteInfoOption(aRios->mPrefix, aRios->mValidLifetime, aRios->mPreference));
914     }
915 }
916 
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Pio * aPios,uint16_t aNumPios,const Rio * aRios,uint16_t aNumRios,const DefaultRoute & aDefaultRoute,const RaFlags & aRaFlags)917 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
918                       const Pio          *aPios,
919                       uint16_t            aNumPios,
920                       const Rio          *aRios,
921                       uint16_t            aNumRios,
922                       const DefaultRoute &aDefaultRoute,
923                       const RaFlags      &aRaFlags)
924 {
925     Ip6::Nd::RouterAdvert::TxMessage raMsg;
926     Icmp6Packet                      packet;
927 
928     BuildRouterAdvert(raMsg, aPios, aNumPios, aRios, aNumRios, aDefaultRoute, aRaFlags);
929     raMsg.GetAsPacket(packet);
930 
931     SendRouterAdvert(aRouterAddress, packet);
932     Log("Sending RA from router %s", aRouterAddress.ToString().AsCString());
933     LogRouterAdvert(packet);
934 }
935 
936 template <uint16_t kNumPios, uint16_t kNumRios>
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Pio (& aPios)[kNumPios],const Rio (& aRios)[kNumRios],const DefaultRoute & aDefaultRoute=DefaultRoute (0,NetworkData::kRoutePreferenceMedium),const RaFlags & aRaFlags=RaFlags ())937 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
938                       const Pio (&aPios)[kNumPios],
939                       const Rio (&aRios)[kNumRios],
940                       const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium),
941                       const RaFlags      &aRaFlags      = RaFlags())
942 {
943     SendRouterAdvert(aRouterAddress, aPios, kNumPios, aRios, kNumRios, aDefaultRoute, aRaFlags);
944 }
945 
946 template <uint16_t kNumPios>
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Pio (& aPios)[kNumPios],const DefaultRoute & aDefaultRoute=DefaultRoute (0,NetworkData::kRoutePreferenceMedium),const RaFlags & aRaFlags=RaFlags ())947 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
948                       const Pio (&aPios)[kNumPios],
949                       const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium),
950                       const RaFlags      &aRaFlags      = RaFlags())
951 {
952     SendRouterAdvert(aRouterAddress, aPios, kNumPios, nullptr, 0, aDefaultRoute, aRaFlags);
953 }
954 
955 template <uint16_t kNumRios>
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Rio (& aRios)[kNumRios],const DefaultRoute & aDefaultRoute=DefaultRoute (0,NetworkData::kRoutePreferenceMedium),const RaFlags & aRaFlags=RaFlags ())956 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
957                       const Rio (&aRios)[kNumRios],
958                       const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium),
959                       const RaFlags      &aRaFlags      = RaFlags())
960 {
961     SendRouterAdvert(aRouterAddress, nullptr, 0, aRios, kNumRios, aDefaultRoute, aRaFlags);
962 }
963 
SendRouterAdvert(const Ip6::Address & aRouterAddress,const DefaultRoute & aDefaultRoute,const RaFlags & aRaFlags=RaFlags ())964 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
965                       const DefaultRoute &aDefaultRoute,
966                       const RaFlags      &aRaFlags = RaFlags())
967 {
968     SendRouterAdvert(aRouterAddress, nullptr, 0, nullptr, 0, aDefaultRoute, aRaFlags);
969 }
970 
SendRouterAdvert(const Ip6::Address & aRouterAddress,const RaFlags & aRaFlags)971 void SendRouterAdvert(const Ip6::Address &aRouterAddress, const RaFlags &aRaFlags)
972 {
973     SendRouterAdvert(aRouterAddress, nullptr, 0, nullptr, 0, DefaultRoute(0, NetworkData::kRoutePreferenceMedium),
974                      aRaFlags);
975 }
976 
SendRouterAdvertToBorderRoutingProcessIcmp6Ra(const Pio (& aPios)[kNumPios])977 template <uint16_t kNumPios> void SendRouterAdvertToBorderRoutingProcessIcmp6Ra(const Pio (&aPios)[kNumPios])
978 {
979     Ip6::Nd::RouterAdvert::TxMessage raMsg;
980     Icmp6Packet                      packet;
981 
982     BuildRouterAdvert(raMsg, aPios, kNumPios, nullptr, 0, DefaultRoute(0, NetworkData::kRoutePreferenceMedium),
983                       RaFlags());
984     raMsg.GetAsPacket(packet);
985 
986     otPlatBorderRoutingProcessIcmp6Ra(sInstance, packet.GetBytes(), packet.GetLength());
987     Log("Passing RA to otPlatBorderRoutingProcessIcmp6Ra");
988     LogRouterAdvert(packet);
989 }
990 
991 struct OnLinkPrefix : public Pio
992 {
OnLinkPrefixot::OnLinkPrefix993     OnLinkPrefix(const Ip6::Prefix  &aPrefix,
994                  uint32_t            aValidLifetime,
995                  uint32_t            aPreferredLifetime,
996                  const Ip6::Address &aRouterAddress)
997         : Pio(aPrefix, aValidLifetime, aPreferredLifetime)
998         , mRouterAddress(aRouterAddress)
999     {
1000     }
1001 
1002     const Ip6::Address &mRouterAddress;
1003 };
1004 
1005 struct RoutePrefix : public Rio
1006 {
RoutePrefixot::RoutePrefix1007     RoutePrefix(const Ip6::Prefix  &aPrefix,
1008                 uint32_t            aValidLifetime,
1009                 RoutePreference     aPreference,
1010                 const Ip6::Address &aRouterAddress)
1011         : Rio(aPrefix, aValidLifetime, aPreference)
1012         , mRouterAddress(aRouterAddress)
1013     {
1014     }
1015 
1016     const Ip6::Address &mRouterAddress;
1017 };
1018 
1019 template <uint16_t kNumOnLinkPrefixes, uint16_t kNumRoutePrefixes>
VerifyPrefixTable(const OnLinkPrefix (& aOnLinkPrefixes)[kNumOnLinkPrefixes],const RoutePrefix (& aRoutePrefixes)[kNumRoutePrefixes])1020 void VerifyPrefixTable(const OnLinkPrefix (&aOnLinkPrefixes)[kNumOnLinkPrefixes],
1021                        const RoutePrefix (&aRoutePrefixes)[kNumRoutePrefixes])
1022 {
1023     VerifyPrefixTable(aOnLinkPrefixes, kNumOnLinkPrefixes, aRoutePrefixes, kNumRoutePrefixes);
1024 }
1025 
VerifyPrefixTable(const OnLinkPrefix (& aOnLinkPrefixes)[kNumOnLinkPrefixes])1026 template <uint16_t kNumOnLinkPrefixes> void VerifyPrefixTable(const OnLinkPrefix (&aOnLinkPrefixes)[kNumOnLinkPrefixes])
1027 {
1028     VerifyPrefixTable(aOnLinkPrefixes, kNumOnLinkPrefixes, nullptr, 0);
1029 }
1030 
VerifyPrefixTable(const RoutePrefix (& aRoutePrefixes)[kNumRoutePrefixes])1031 template <uint16_t kNumRoutePrefixes> void VerifyPrefixTable(const RoutePrefix (&aRoutePrefixes)[kNumRoutePrefixes])
1032 {
1033     VerifyPrefixTable(nullptr, 0, aRoutePrefixes, kNumRoutePrefixes);
1034 }
1035 
VerifyPrefixTable(const OnLinkPrefix * aOnLinkPrefixes,uint16_t aNumOnLinkPrefixes,const RoutePrefix * aRoutePrefixes,uint16_t aNumRoutePrefixes)1036 void VerifyPrefixTable(const OnLinkPrefix *aOnLinkPrefixes,
1037                        uint16_t            aNumOnLinkPrefixes,
1038                        const RoutePrefix  *aRoutePrefixes,
1039                        uint16_t            aNumRoutePrefixes)
1040 {
1041     BorderRouter::RoutingManager::PrefixTableIterator iter;
1042     BorderRouter::RoutingManager::PrefixTableEntry    entry;
1043     uint16_t                                          onLinkPrefixCount = 0;
1044     uint16_t                                          routePrefixCount  = 0;
1045 
1046     Log("VerifyPrefixTable()");
1047 
1048     sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
1049 
1050     while (sInstance->Get<BorderRouter::RoutingManager>().GetNextPrefixTableEntry(iter, entry) == kErrorNone)
1051     {
1052         bool didFind = false;
1053 
1054         if (entry.mIsOnLink)
1055         {
1056             Log("   on-link prefix:%s, valid:%u, preferred:%u, router:%s, age:%u",
1057                 AsCoreType(&entry.mPrefix).ToString().AsCString(), entry.mValidLifetime, entry.mPreferredLifetime,
1058                 AsCoreType(&entry.mRouter.mAddress).ToString().AsCString(), entry.mMsecSinceLastUpdate / 1000);
1059 
1060             onLinkPrefixCount++;
1061 
1062             for (uint16_t index = 0; index < aNumOnLinkPrefixes; index++)
1063             {
1064                 const OnLinkPrefix &onLinkPrefix = aOnLinkPrefixes[index];
1065 
1066                 if ((onLinkPrefix.mPrefix == AsCoreType(&entry.mPrefix)) &&
1067                     (AsCoreType(&entry.mRouter.mAddress) == onLinkPrefix.mRouterAddress))
1068                 {
1069                     VerifyOrQuit(entry.mValidLifetime == onLinkPrefix.mValidLifetime);
1070                     VerifyOrQuit(entry.mPreferredLifetime == onLinkPrefix.mPreferredLifetime);
1071                     didFind = true;
1072                     break;
1073                 }
1074             }
1075         }
1076         else
1077         {
1078             Log("   route prefix:%s, valid:%u, prf:%s, router:%s, age:%u",
1079                 AsCoreType(&entry.mPrefix).ToString().AsCString(), entry.mValidLifetime,
1080                 PreferenceToString(entry.mRoutePreference), AsCoreType(&entry.mRouter.mAddress).ToString().AsCString(),
1081                 entry.mMsecSinceLastUpdate / 1000);
1082 
1083             routePrefixCount++;
1084 
1085             for (uint16_t index = 0; index < aNumRoutePrefixes; index++)
1086             {
1087                 const RoutePrefix &routePrefix = aRoutePrefixes[index];
1088 
1089                 if ((routePrefix.mPrefix == AsCoreType(&entry.mPrefix)) &&
1090                     (AsCoreType(&entry.mRouter.mAddress) == routePrefix.mRouterAddress))
1091                 {
1092                     VerifyOrQuit(entry.mValidLifetime == routePrefix.mValidLifetime);
1093                     VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == routePrefix.mPreference);
1094                     didFind = true;
1095                     break;
1096                 }
1097             }
1098         }
1099 
1100         VerifyOrQuit(didFind);
1101     }
1102 
1103     VerifyOrQuit(onLinkPrefixCount == aNumOnLinkPrefixes);
1104     VerifyOrQuit(routePrefixCount == aNumRoutePrefixes);
1105 }
1106 
VerifyPrefixTableIsEmpty(void)1107 void VerifyPrefixTableIsEmpty(void) { VerifyPrefixTable(nullptr, 0, nullptr, 0); }
1108 
1109 struct InfraRouter
1110 {
InfraRouterot::InfraRouter1111     InfraRouter(const Ip6::Address &aAddress,
1112                 bool                aManagedAddressConfigFlag,
1113                 bool                aOtherConfigFlag,
1114                 bool                aStubRouterFlag,
1115                 bool                aIsLocalDevice = false)
1116         : mAddress(aAddress)
1117         , mIsLocalDevice(aIsLocalDevice)
1118     {
1119         mFlags.Clear();
1120         mFlags.mManagedAddressConfigFlag = aManagedAddressConfigFlag;
1121         mFlags.mOtherConfigFlag          = aOtherConfigFlag;
1122         mFlags.mStubRouterFlag           = aStubRouterFlag;
1123     }
1124 
1125     Ip6::Address mAddress;
1126     RaFlags      mFlags;
1127     bool         mIsLocalDevice;
1128 };
1129 
VerifyDiscoveredRouters(const InfraRouter (& aRouters)[kNumRouters])1130 template <uint16_t kNumRouters> void VerifyDiscoveredRouters(const InfraRouter (&aRouters)[kNumRouters])
1131 {
1132     VerifyDiscoveredRouters(aRouters, kNumRouters);
1133 }
1134 
VerifyDiscoveredRouters(const InfraRouter * aRouters,uint16_t aNumRouters)1135 void VerifyDiscoveredRouters(const InfraRouter *aRouters, uint16_t aNumRouters)
1136 {
1137     BorderRouter::RoutingManager::PrefixTableIterator iter;
1138     BorderRouter::RoutingManager::RouterEntry         entry;
1139     uint16_t                                          count = 0;
1140 
1141     Log("VerifyDiscoveredRouters()");
1142 
1143     sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
1144 
1145     while (sInstance->Get<BorderRouter::RoutingManager>().GetNextRouterEntry(iter, entry) == kErrorNone)
1146     {
1147         bool didFind = false;
1148 
1149         Log("   address:%s, M:%u, O:%u, StubRouter:%u%s", AsCoreType(&entry.mAddress).ToString().AsCString(),
1150             entry.mManagedAddressConfigFlag, entry.mOtherConfigFlag, entry.mStubRouterFlag,
1151             entry.mIsLocalDevice ? " (this BR)" : "");
1152 
1153         for (uint16_t index = 0; index < aNumRouters; index++)
1154         {
1155             if (AsCoreType(&entry.mAddress) == aRouters[index].mAddress)
1156             {
1157                 VerifyOrQuit(entry.mManagedAddressConfigFlag == aRouters[index].mFlags.mManagedAddressConfigFlag);
1158                 VerifyOrQuit(entry.mOtherConfigFlag == aRouters[index].mFlags.mOtherConfigFlag);
1159                 VerifyOrQuit(entry.mStubRouterFlag == aRouters[index].mFlags.mStubRouterFlag);
1160                 VerifyOrQuit(entry.mIsLocalDevice == aRouters[index].mIsLocalDevice);
1161                 didFind = true;
1162             }
1163         }
1164 
1165         VerifyOrQuit(didFind);
1166         count++;
1167     }
1168 
1169     VerifyOrQuit(count == aNumRouters);
1170 }
1171 
VerifyDiscoveredRoutersIsEmpty(void)1172 void VerifyDiscoveredRoutersIsEmpty(void) { VerifyDiscoveredRouters(nullptr, 0); }
1173 
VerifyFavoredOnLinkPrefix(const Ip6::Prefix & aPrefix)1174 void VerifyFavoredOnLinkPrefix(const Ip6::Prefix &aPrefix)
1175 {
1176     Ip6::Prefix favoredPrefix;
1177 
1178     Log("VerifyFavoredOnLinkPrefix(%s)", aPrefix.ToString().AsCString());
1179 
1180     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetFavoredOnLinkPrefix(favoredPrefix));
1181     VerifyOrQuit(favoredPrefix == aPrefix);
1182 }
1183 
InitTest(bool aEnablBorderRouting=false,bool aAfterReset=false)1184 void InitTest(bool aEnablBorderRouting = false, bool aAfterReset = false)
1185 {
1186     uint32_t delay = 10000;
1187 
1188     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1189     // Initialize OT instance.
1190 
1191     sNow      = 0;
1192     sAlarmOn  = false;
1193     sInstance = static_cast<Instance *>(testInitInstance());
1194 
1195     if (aAfterReset)
1196     {
1197         delay += 26000; // leader reset sync delay
1198     }
1199 
1200     memset(&sRadioTxFrame, 0, sizeof(sRadioTxFrame));
1201     sRadioTxFrame.mPsdu = sRadioTxFramePsdu;
1202     sRadioTxOngoing     = false;
1203 
1204     SuccessOrQuit(sInfraIfAddress.FromString(kInfraIfAddress));
1205 
1206     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1207     // Initialize and start Border Router and Thread operation.
1208 
1209     SuccessOrQuit(otBorderRoutingInit(sInstance, kInfraIfIndex, /* aInfraIfIsRunning */ true));
1210 
1211     otOperationalDatasetTlvs datasetTlvs;
1212 
1213     otDatasetConvertToTlvs(&kDataset, &datasetTlvs);
1214     SuccessOrQuit(otDatasetSetActiveTlvs(sInstance, &datasetTlvs));
1215 
1216     SuccessOrQuit(otIp6SetEnabled(sInstance, true));
1217     SuccessOrQuit(otThreadSetEnabled(sInstance, true));
1218     SuccessOrQuit(otBorderRoutingSetEnabled(sInstance, aEnablBorderRouting));
1219 
1220     // Reset all test flags
1221     sRsEmitted   = false;
1222     sRaValidated = false;
1223     sExpectedPio = kNoPio;
1224     sExpectedRios.Clear();
1225     sRespondToNs              = true;
1226     sExpectedRaHeaderFlags    = kRaHeaderFlagsNone;
1227     sCheckRaHeaderLifetime    = true;
1228     sExpectedRaHeaderLifetime = 0;
1229 
1230     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1231     // Ensure device starts as leader.
1232 
1233     AdvanceTime(delay);
1234 
1235     VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
1236 }
1237 
FinalizeTest(void)1238 void FinalizeTest(void)
1239 {
1240     SuccessOrQuit(otIp6SetEnabled(sInstance, false));
1241     SuccessOrQuit(otThreadSetEnabled(sInstance, false));
1242     SuccessOrQuit(otInstanceErasePersistentInfo(sInstance));
1243     testFreeInstance(sInstance);
1244 }
1245 
1246 //---------------------------------------------------------------------------------------------------------------------
1247 
TestSamePrefixesFromMultipleRouters(void)1248 void TestSamePrefixesFromMultipleRouters(void)
1249 {
1250     Ip6::Prefix  localOnLink;
1251     Ip6::Prefix  localOmr;
1252     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
1253     Ip6::Prefix  routePrefix    = PrefixFromString("2000:1234:5678::", 64);
1254     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
1255     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
1256     uint16_t     heapAllocations;
1257 
1258     Log("--------------------------------------------------------------------------------------------");
1259     Log("TestSamePrefixesFromMultipleRouters");
1260 
1261     InitTest();
1262 
1263     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1264     // Start Routing Manager. Check emitted RS and RA messages.
1265 
1266     sRsEmitted   = false;
1267     sRaValidated = false;
1268     sExpectedPio = kPioAdvertisingLocalOnLink;
1269     sExpectedRios.Clear();
1270 
1271     heapAllocations = sHeapAllocatedPtrs.GetLength();
1272     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1273 
1274     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1275     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1276 
1277     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1278     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1279 
1280     sExpectedRios.Add(localOmr);
1281 
1282     AdvanceTime(30000);
1283 
1284     VerifyOrQuit(sRsEmitted);
1285     VerifyOrQuit(sRaValidated);
1286     VerifyOrQuit(sExpectedRios.SawAll());
1287     Log("Received RA was validated");
1288 
1289     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1290     // Check Network Data to include the local OMR and on-link prefix.
1291 
1292     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1293     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1294 
1295     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1296     // Send an RA from router A with a new on-link (PIO) and route prefix (RIO).
1297 
1298     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
1299                      {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1300 
1301     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1302     // Check that the local on-link prefix is now deprecating in the new RA.
1303 
1304     sRaValidated = false;
1305     sExpectedPio = kPioDeprecatingLocalOnLink;
1306 
1307     AdvanceTime(10000);
1308     VerifyOrQuit(sRaValidated);
1309 
1310     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1311     // Check the discovered prefix table and ensure info from router A
1312     // is present in the table.
1313 
1314     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1315                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1316 
1317     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1318     // Check Network Data to include new prefixes from router A.
1319 
1320     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
1321     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1322 
1323     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1324     // Send the same RA again from router A with the on-link (PIO) and route prefix (RIO).
1325 
1326     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
1327                      {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1328 
1329     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1330     // Check the discovered prefix table and ensure info from router A
1331     // remains unchanged.
1332 
1333     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1334                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1335 
1336     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1337     // Send an RA from router B with same route prefix (RIO) but with
1338     // high route preference.
1339 
1340     SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
1341 
1342     AdvanceTime(10000);
1343 
1344     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1345     // Check the discovered prefix table and ensure info from router B
1346     // is also included in the table.
1347 
1348     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1349                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA),
1350                        RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
1351 
1352     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1353     // Check Network Data.
1354 
1355     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
1356     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1357 
1358     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1359     // Send an RA from router B removing the route prefix.
1360 
1361     SendRouterAdvert(routerAddressB, {Rio(routePrefix, 0, NetworkData::kRoutePreferenceHigh)});
1362 
1363     AdvanceTime(10000);
1364 
1365     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1366     // Check the discovered prefix table and ensure info from router B
1367     // is now removed from the table.
1368 
1369     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1370                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1371 
1372     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1373     // Check Network Data.
1374 
1375     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1376 
1377     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1378 
1379     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
1380     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1381 
1382     Log("End of TestSamePrefixesFromMultipleRouters");
1383 
1384     FinalizeTest();
1385 }
1386 
TestOmrSelection(void)1387 void TestOmrSelection(void)
1388 {
1389     Ip6::Prefix                     localOnLink;
1390     Ip6::Prefix                     localOmr;
1391     Ip6::Prefix                     omrPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
1392     NetworkData::OnMeshPrefixConfig prefixConfig;
1393     uint16_t                        heapAllocations;
1394 
1395     Log("--------------------------------------------------------------------------------------------");
1396     Log("TestOmrSelection");
1397 
1398     InitTest();
1399 
1400     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1401     // Start Routing Manager. Check emitted RS and RA messages.
1402 
1403     sRsEmitted   = false;
1404     sRaValidated = false;
1405     sExpectedPio = kPioAdvertisingLocalOnLink;
1406     sExpectedRios.Clear();
1407 
1408     heapAllocations = sHeapAllocatedPtrs.GetLength();
1409     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1410 
1411     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1412     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1413 
1414     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1415     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1416 
1417     sExpectedRios.Add(localOmr);
1418 
1419     AdvanceTime(30000);
1420 
1421     VerifyOrQuit(sRsEmitted);
1422     VerifyOrQuit(sRaValidated);
1423     VerifyOrQuit(sExpectedRios.SawAll());
1424     VerifyOrQuit(sExpectedRios[0].mLifetime == kRioValidLifetime);
1425     VerifyOrQuit(sExpectedRios[0].mPreference == NetworkData::kRoutePreferenceMedium);
1426 
1427     Log("Received RA was validated");
1428 
1429     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1430     // Check Network Data to include the local OMR and on-link prefix.
1431 
1432     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1433     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1434 
1435     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1436     // Add a new OMR prefix directly into net data. The new prefix should
1437     // be favored over the local OMR prefix.
1438 
1439     prefixConfig.Clear();
1440     prefixConfig.mPrefix       = omrPrefix;
1441     prefixConfig.mStable       = true;
1442     prefixConfig.mSlaac        = true;
1443     prefixConfig.mPreferred    = true;
1444     prefixConfig.mOnMesh       = true;
1445     prefixConfig.mDefaultRoute = false;
1446     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1447 
1448     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1449     SuccessOrQuit(otBorderRouterRegister(sInstance));
1450 
1451     AdvanceTime(100);
1452 
1453     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1454     // Make sure BR emits RA with the new OMR prefix now, and deprecates the old OMR prefix.
1455 
1456     sRaValidated = false;
1457     sExpectedPio = kPioAdvertisingLocalOnLink;
1458     sExpectedRios.Clear();
1459     sExpectedRios.Add(omrPrefix);
1460     sExpectedRios.Add(localOmr);
1461 
1462     AdvanceTime(20000);
1463 
1464     VerifyOrQuit(sRaValidated);
1465     VerifyOrQuit(sExpectedRios.SawAll());
1466     VerifyOrQuit(sExpectedRios[0].mLifetime == kRioValidLifetime);
1467     VerifyOrQuit(sExpectedRios[0].mPreference == NetworkData::kRoutePreferenceMedium);
1468     VerifyOrQuit(sExpectedRios[1].mLifetime <= kRioDeprecatingLifetime);
1469     VerifyOrQuit(sExpectedRios[1].mPreference == NetworkData::kRoutePreferenceLow);
1470 
1471     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1472     // Check Network Data. We should now see that the local OMR prefix
1473     // is removed.
1474 
1475     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ false);
1476     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1477 
1478     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1479     // Remove the OMR prefix previously added in net data.
1480 
1481     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &omrPrefix));
1482     SuccessOrQuit(otBorderRouterRegister(sInstance));
1483 
1484     AdvanceTime(100);
1485 
1486     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1487     // Make sure BR emits RA with local OMR prefix again and start
1488     // deprecating the previously added OMR prefix.
1489 
1490     sRaValidated = false;
1491     sExpectedRios.Clear();
1492     sExpectedRios.Add(omrPrefix);
1493     sExpectedRios.Add(localOmr);
1494 
1495     AdvanceTime(20000);
1496 
1497     VerifyOrQuit(sRaValidated);
1498     VerifyOrQuit(sExpectedRios.SawAll());
1499     VerifyOrQuit(sExpectedRios[0].mLifetime <= kRioDeprecatingLifetime);
1500     VerifyOrQuit(sExpectedRios[0].mPreference == NetworkData::kRoutePreferenceLow);
1501     VerifyOrQuit(sExpectedRios[1].mLifetime == kRioValidLifetime);
1502     VerifyOrQuit(sExpectedRios[1].mPreference == NetworkData::kRoutePreferenceMedium);
1503 
1504     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1505     // Check Network Data. We should see that the local OMR prefix is
1506     // added again.
1507 
1508     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1509     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1510 
1511     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1512     // Wait enough for old deprecating OMR prefix deprecating to expire.
1513 
1514     sRaValidated = false;
1515     sExpectedRios.Clear();
1516     sExpectedRios.Add(omrPrefix);
1517     sExpectedRios.Add(localOmr);
1518 
1519     AdvanceTime(310000);
1520 
1521     VerifyOrQuit(sRaValidated);
1522     VerifyOrQuit(sExpectedRios.SawAll());
1523     VerifyOrQuit(sExpectedRios[0].mLifetime == 0);
1524     VerifyOrQuit(sExpectedRios[1].mLifetime == kRioValidLifetime);
1525     VerifyOrQuit(sExpectedRios[0].mPreference == NetworkData::kRoutePreferenceLow);
1526 
1527     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1528 
1529     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
1530     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1531 
1532     Log("End of TestOmrSelection");
1533     FinalizeTest();
1534 }
1535 
TestDefaultRoute(void)1536 void TestDefaultRoute(void)
1537 {
1538     Ip6::Prefix                     localOnLink;
1539     Ip6::Prefix                     localOmr;
1540     Ip6::Prefix                     omrPrefix      = PrefixFromString("2000:0000:1111:4444::", 64);
1541     Ip6::Prefix                     defaultRoute   = PrefixFromString("::", 0);
1542     Ip6::Address                    routerAddressA = AddressFromString("fd00::aaaa");
1543     NetworkData::OnMeshPrefixConfig prefixConfig;
1544     uint16_t                        heapAllocations;
1545 
1546     Log("--------------------------------------------------------------------------------------------");
1547     Log("TestDefaultRoute");
1548 
1549     InitTest();
1550 
1551     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1552     // Start Routing Manager. Check emitted RS and RA messages.
1553 
1554     sRsEmitted   = false;
1555     sRaValidated = false;
1556     sExpectedPio = kPioAdvertisingLocalOnLink;
1557     sExpectedRios.Clear();
1558 
1559     heapAllocations = sHeapAllocatedPtrs.GetLength();
1560     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1561 
1562     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1563     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1564 
1565     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1566     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1567 
1568     sExpectedRios.Add(localOmr);
1569 
1570     AdvanceTime(30000);
1571 
1572     VerifyOrQuit(sRsEmitted);
1573     VerifyOrQuit(sRaValidated);
1574     VerifyOrQuit(sExpectedRios.SawAll());
1575     Log("Received RA was validated");
1576 
1577     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1578     // Check Network Data to include the local OMR and ULA prefix.
1579 
1580     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1581     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1582 
1583     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1584     // Send RA from router A advertising a default route.
1585 
1586     SendRouterAdvert(routerAddressA, DefaultRoute(kValidLitime, NetworkData::kRoutePreferenceLow));
1587 
1588     AdvanceTime(10000);
1589 
1590     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1591     // Check the discovered prefix table and ensure default route
1592     // from router A is in the table.
1593 
1594     VerifyPrefixTable({RoutePrefix(defaultRoute, kValidLitime, NetworkData::kRoutePreferenceLow, routerAddressA)});
1595 
1596     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1597     // Check Network Data. We should not see default route in
1598     // Network Data yet since there is no infrastructure-derived
1599     // OMR prefix (with preference medium or higher).
1600 
1601     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1602     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1603 
1604     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1605     // Add an OMR prefix directly into Network Data with
1606     // preference medium (infrastructure-derived).
1607 
1608     prefixConfig.Clear();
1609     prefixConfig.mPrefix       = omrPrefix;
1610     prefixConfig.mStable       = true;
1611     prefixConfig.mSlaac        = true;
1612     prefixConfig.mPreferred    = true;
1613     prefixConfig.mOnMesh       = true;
1614     prefixConfig.mDefaultRoute = true;
1615     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1616 
1617     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1618     SuccessOrQuit(otBorderRouterRegister(sInstance));
1619 
1620     AdvanceTime(10000);
1621 
1622     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1623     // Check Network Data. Now that we have an infrastructure-derived
1624     // OMR prefix, the default route should be published.
1625 
1626     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1627     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1628 
1629     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1630     // Remove the OMR prefix from Network Data.
1631 
1632     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &omrPrefix));
1633     SuccessOrQuit(otBorderRouterRegister(sInstance));
1634 
1635     AdvanceTime(10000);
1636 
1637     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1638     // Check Network Data. We should again go back to ULA prefix. The
1639     // default route advertised by router A should be still present in
1640     // the discovered prefix table.
1641 
1642     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1643     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1644 
1645     VerifyPrefixTable({RoutePrefix(defaultRoute, kValidLitime, NetworkData::kRoutePreferenceLow, routerAddressA)});
1646 
1647     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1648     // Add the OMR prefix again.
1649 
1650     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1651     SuccessOrQuit(otBorderRouterRegister(sInstance));
1652 
1653     AdvanceTime(10000);
1654 
1655     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1656     // Check Network Data. Again the default route should be published.
1657 
1658     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1659     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1660 
1661     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1662     // Send RA from router A removing the default route.
1663 
1664     SendRouterAdvert(routerAddressA, DefaultRoute(0, NetworkData::kRoutePreferenceLow));
1665 
1666     AdvanceTime(10000);
1667 
1668     VerifyPrefixTableIsEmpty();
1669 
1670     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1671     // Check Network Data. Now that router A no longer advertised
1672     // a default-route, we should go back to publishing ULA route.
1673 
1674     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1675     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1676 
1677     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1678     // Send RA from router A again advertising a default route.
1679 
1680     SendRouterAdvert(routerAddressA, DefaultRoute(kValidLitime, NetworkData::kRoutePreferenceLow));
1681 
1682     AdvanceTime(10000);
1683 
1684     VerifyPrefixTable({RoutePrefix(defaultRoute, kValidLitime, NetworkData::kRoutePreferenceLow, routerAddressA)});
1685 
1686     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1687     // Check Network Data. We should see default route published.
1688 
1689     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1690     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1691 
1692     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1693 
1694     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
1695     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1696 
1697     Log("End of TestDefaultRoute");
1698 
1699     FinalizeTest();
1700 }
1701 
TestAdvNonUlaRoute(void)1702 void TestAdvNonUlaRoute(void)
1703 {
1704     Ip6::Prefix                     localOnLink;
1705     Ip6::Prefix                     localOmr;
1706     Ip6::Prefix                     omrPrefix      = PrefixFromString("2000:0000:1111:4444::", 64);
1707     Ip6::Prefix                     routePrefix    = PrefixFromString("2000:1234:5678::", 64);
1708     Ip6::Address                    routerAddressA = AddressFromString("fd00::aaaa");
1709     NetworkData::OnMeshPrefixConfig prefixConfig;
1710     uint16_t                        heapAllocations;
1711 
1712     Log("--------------------------------------------------------------------------------------------");
1713     Log("TestAdvNonUlaRoute");
1714 
1715     InitTest();
1716 
1717     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1718     // Start Routing Manager. Check emitted RS and RA messages.
1719 
1720     sRsEmitted   = false;
1721     sRaValidated = false;
1722     sExpectedPio = kPioAdvertisingLocalOnLink;
1723     sExpectedRios.Clear();
1724 
1725     heapAllocations = sHeapAllocatedPtrs.GetLength();
1726     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1727 
1728     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1729     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1730 
1731     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1732     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1733 
1734     sExpectedRios.Add(localOmr);
1735 
1736     AdvanceTime(30000);
1737 
1738     VerifyOrQuit(sRsEmitted);
1739     VerifyOrQuit(sRaValidated);
1740     VerifyOrQuit(sExpectedRios.SawAll());
1741     Log("Received RA was validated");
1742 
1743     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1744     // Check Network Data to include the local OMR and ULA prefix.
1745 
1746     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1747     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1748 
1749     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1750     // Send RA from router A advertising a non-ULA.
1751 
1752     SendRouterAdvert(routerAddressA, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1753 
1754     AdvanceTime(10000);
1755 
1756     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1757     // Check the discovered prefix table and ensure the non-ULA
1758     // from router A is in the table.
1759 
1760     VerifyPrefixTable({RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1761 
1762     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1763     // Check Network Data. We should not see default route in
1764     // Network Data yet since there is no infrastructure-derived
1765     // OMR prefix (with preference medium or higher).
1766 
1767     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1768     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1769 
1770     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1771     // Add an OMR prefix directly into Network Data with
1772     // preference medium (infrastructure-derived).
1773 
1774     prefixConfig.Clear();
1775     prefixConfig.mPrefix       = omrPrefix;
1776     prefixConfig.mStable       = true;
1777     prefixConfig.mSlaac        = true;
1778     prefixConfig.mPreferred    = true;
1779     prefixConfig.mOnMesh       = true;
1780     prefixConfig.mDefaultRoute = true;
1781     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1782 
1783     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1784     SuccessOrQuit(otBorderRouterRegister(sInstance));
1785 
1786     AdvanceTime(10000);
1787 
1788     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1789     // Check Network Data. Now that we have an infrastructure-derived
1790     // OMR prefix, the default route should be published.
1791 
1792     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1793     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1794 
1795     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1796     // Remove the OMR prefix from Network Data.
1797 
1798     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &omrPrefix));
1799     SuccessOrQuit(otBorderRouterRegister(sInstance));
1800 
1801     AdvanceTime(10000);
1802 
1803     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1804     // Check Network Data. We should again go back to ULA prefix. The
1805     // non-ULA route advertised by router A should be still present in
1806     // the discovered prefix table.
1807 
1808     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1809     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1810 
1811     VerifyPrefixTable({RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1812 
1813     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1814     // Add the OMR prefix again.
1815 
1816     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1817     SuccessOrQuit(otBorderRouterRegister(sInstance));
1818 
1819     AdvanceTime(10000);
1820 
1821     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1822     // Check Network Data. Again the default route should be published.
1823 
1824     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1825     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1826 
1827     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1828     // Send RA from router A removing the route.
1829 
1830     SendRouterAdvert(routerAddressA, {Rio(routePrefix, 0, NetworkData::kRoutePreferenceMedium)});
1831 
1832     AdvanceTime(10000);
1833 
1834     VerifyPrefixTableIsEmpty();
1835 
1836     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1837     // Check Network Data. Now that router A no longer advertised
1838     // the route, we should go back to publishing the ULA route.
1839 
1840     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1841     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1842 
1843     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1844     // Send RA from router A again advertising the route again.
1845 
1846     SendRouterAdvert(routerAddressA, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1847 
1848     AdvanceTime(10000);
1849 
1850     VerifyPrefixTable({RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1851 
1852     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1853     // Check Network Data. We should see default route published.
1854 
1855     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1856     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1857 
1858     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1859 
1860     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
1861     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1862 
1863     Log("End of TestAdvNonUlaRoute");
1864 
1865     FinalizeTest();
1866 }
1867 
TestFavoredOnLinkPrefix(void)1868 void TestFavoredOnLinkPrefix(void)
1869 {
1870     Ip6::Prefix  localOnLink;
1871     Ip6::Prefix  localOmr;
1872     Ip6::Prefix  onLinkPrefixA  = PrefixFromString("2000:abba:baba:aaaa::", 64);
1873     Ip6::Prefix  onLinkPrefixB  = PrefixFromString("2000:abba:baba:bbbb::", 64);
1874     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
1875     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
1876     uint16_t     heapAllocations;
1877 
1878     Log("--------------------------------------------------------------------------------------------");
1879     Log("TestFavoredOnLinkPrefix");
1880 
1881     InitTest();
1882 
1883     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1884     // Start Routing Manager. Check emitted RS and RA messages.
1885 
1886     sRsEmitted   = false;
1887     sRaValidated = false;
1888     sExpectedPio = kPioAdvertisingLocalOnLink;
1889     sExpectedRios.Clear();
1890 
1891     heapAllocations = sHeapAllocatedPtrs.GetLength();
1892     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1893 
1894     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1895     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1896 
1897     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1898     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1899 
1900     sExpectedRios.Add(localOmr);
1901 
1902     AdvanceTime(30000);
1903 
1904     VerifyOrQuit(sRsEmitted);
1905     VerifyOrQuit(sRaValidated);
1906     VerifyOrQuit(sExpectedRios.SawAll());
1907     Log("Received RA was validated");
1908 
1909     VerifyFavoredOnLinkPrefix(localOnLink);
1910 
1911     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1912     // Advertise on-link prefix B from router B
1913 
1914     SendRouterAdvert(routerAddressB, {Pio(onLinkPrefixB, kValidLitime, kPreferredLifetime)});
1915 
1916     AdvanceTime(10 * 1000);
1917 
1918     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1919     // Check the discovered prefix table and ensure on-link prefix B is
1920     // now the favored on-link prefix
1921 
1922     VerifyPrefixTable({OnLinkPrefix(onLinkPrefixB, kValidLitime, kPreferredLifetime, routerAddressB)});
1923     VerifyFavoredOnLinkPrefix(onLinkPrefixB);
1924 
1925     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1926     // Advertise on-link prefix A from router A with a short
1927     // preferred lifetime (less than 1800 which is the threshold for it
1928     // to be considered a valid favored on-link prefix).
1929 
1930     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefixA, kValidLitime, 1799)});
1931 
1932     AdvanceTime(10 * 1000);
1933 
1934     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1935     // Check the discovered prefix table and ensure on-link prefix B is
1936     // still the favored on-link prefix.
1937 
1938     VerifyPrefixTable({OnLinkPrefix(onLinkPrefixB, kValidLitime, kPreferredLifetime, routerAddressB),
1939                        OnLinkPrefix(onLinkPrefixA, kValidLitime, 1799, routerAddressA)});
1940 
1941     VerifyFavoredOnLinkPrefix(onLinkPrefixB);
1942 
1943     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1944     // Advertise on-link prefix A from router A with a long
1945     // preferred lifetime now.
1946 
1947     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefixA, kValidLitime, kPreferredLifetime)});
1948 
1949     AdvanceTime(10 * 1000);
1950 
1951     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1952     // Check the discovered prefix table and ensure that now on-link
1953     // prefix A (which is numerically smaller) is considered as
1954     // favored on-link prefix.
1955 
1956     VerifyPrefixTable({OnLinkPrefix(onLinkPrefixB, kValidLitime, kPreferredLifetime, routerAddressB),
1957                        OnLinkPrefix(onLinkPrefixA, kValidLitime, kPreferredLifetime, routerAddressA)});
1958 
1959     VerifyFavoredOnLinkPrefix(onLinkPrefixA);
1960 
1961     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1962     // Deprecate on-link prefix A from router A
1963 
1964     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefixA, kValidLitime, 0)});
1965 
1966     AdvanceTime(10 * 1000);
1967 
1968     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1969     // Check the discovered prefix table and ensure that now on-link
1970     // prefix B is again the  favored on-link prefix.
1971 
1972     VerifyPrefixTable({OnLinkPrefix(onLinkPrefixB, kValidLitime, kPreferredLifetime, routerAddressB),
1973                        OnLinkPrefix(onLinkPrefixA, kValidLitime, 0, routerAddressA)});
1974 
1975     VerifyFavoredOnLinkPrefix(onLinkPrefixB);
1976 
1977     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1978 
1979     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
1980     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1981 
1982     Log("End of TestFavoredOnLinkPrefix");
1983     FinalizeTest();
1984 }
1985 
TestLocalOnLinkPrefixDeprecation(void)1986 void TestLocalOnLinkPrefixDeprecation(void)
1987 {
1988     static constexpr uint32_t kMaxRaTxInterval = 196; // In seconds
1989 
1990     Ip6::Prefix  localOnLink;
1991     Ip6::Prefix  localOmr;
1992     Ip6::Prefix  onLinkPrefix   = PrefixFromString("fd00:abba:baba::", 64);
1993     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
1994     uint32_t     localOnLinkLifetime;
1995     uint16_t     heapAllocations;
1996 
1997     Log("--------------------------------------------------------------------------------------------");
1998     Log("TestLocalOnLinkPrefixDeprecation");
1999 
2000     InitTest();
2001 
2002     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2003     // Start Routing Manager. Check emitted RS and RA messages.
2004 
2005     heapAllocations = sHeapAllocatedPtrs.GetLength();
2006     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2007 
2008     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2009     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2010 
2011     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2012     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2013 
2014     sRsEmitted   = false;
2015     sRaValidated = false;
2016     sExpectedPio = kPioAdvertisingLocalOnLink;
2017     sExpectedRios.Clear();
2018     sExpectedRios.Add(localOmr);
2019 
2020     AdvanceTime(30000);
2021 
2022     VerifyOrQuit(sRsEmitted);
2023     VerifyOrQuit(sRaValidated);
2024     VerifyOrQuit(sExpectedRios.SawAll());
2025     Log("Local on-link prefix is being advertised, lifetime: %d", sOnLinkLifetime);
2026     localOnLinkLifetime = sOnLinkLifetime;
2027 
2028     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2029     // Check Network Data to include the local OMR and on-link prefix.
2030 
2031     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2032     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2033 
2034     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2035     // Send an RA from router A with a new on-link (PIO) which is preferred over
2036     // the local on-link prefix.
2037 
2038     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kInfiniteLifetime, kInfiniteLifetime)});
2039 
2040     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2041     // Check that the local on-link prefix is now deprecating in the new RA.
2042 
2043     sRaValidated = false;
2044     sExpectedPio = kPioDeprecatingLocalOnLink;
2045     sExpectedRios.Clear();
2046     sExpectedRios.Add(localOmr);
2047 
2048     AdvanceTime(10000);
2049     VerifyOrQuit(sRaValidated);
2050     VerifyOrQuit(sExpectedRios.SawAll());
2051     Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
2052     VerifyOrQuit(sOnLinkLifetime < localOnLinkLifetime);
2053     localOnLinkLifetime = sOnLinkLifetime;
2054 
2055     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2056     // Check Network Data. We must see the new on-link prefix from router A
2057     // along with the deprecating local on-link prefix.
2058 
2059     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2060     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2061 
2062     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2063     // Wait for local on-link prefix to expire
2064 
2065     while (localOnLinkLifetime > kMaxRaTxInterval)
2066     {
2067         // Send same RA from router A to keep the on-link prefix alive.
2068 
2069         SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2070 
2071         // Ensure Network Data entries remain as before. Mainly we still
2072         // see the deprecating local on-link prefix.
2073 
2074         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2075         VerifyExternalRouteInNetData(kUlaRoute, kSkipAdvPioCheck);
2076 
2077         // Keep checking the emitted RAs and make sure on-link prefix
2078         // is included with smaller lifetime every time.
2079 
2080         sRaValidated = false;
2081         sExpectedPio = kPioDeprecatingLocalOnLink;
2082         sExpectedRios.Clear();
2083         sExpectedRios.Add(localOmr);
2084 
2085         AdvanceTime(kMaxRaTxInterval * 1000);
2086 
2087         VerifyOrQuit(sRaValidated);
2088         VerifyOrQuit(sExpectedRios.SawAll());
2089         Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
2090         VerifyOrQuit(sOnLinkLifetime < localOnLinkLifetime);
2091         localOnLinkLifetime = sOnLinkLifetime;
2092     }
2093 
2094     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2095     // The local on-link prefix must be expired and should no
2096     // longer be seen in the emitted RA message.
2097 
2098     sRaValidated = false;
2099     sExpectedPio = kNoPio;
2100     sExpectedRios.Clear();
2101     sExpectedRios.Add(localOmr);
2102 
2103     AdvanceTime(kMaxRaTxInterval * 1000);
2104 
2105     VerifyOrQuit(sRaValidated);
2106     VerifyOrQuit(sExpectedRios.SawAll());
2107     Log("On-link prefix is now expired");
2108 
2109     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2110     // Check Network Data.
2111 
2112     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2113     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioCleared);
2114 
2115     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2116 
2117     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2118     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2119 
2120     Log("End of TestLocalOnLinkPrefixDeprecation");
2121 
2122     FinalizeTest();
2123 }
2124 
2125 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
TestDomainPrefixAsOmr(void)2126 void TestDomainPrefixAsOmr(void)
2127 {
2128     Ip6::Prefix                     localOnLink;
2129     Ip6::Prefix                     localOmr;
2130     Ip6::Prefix                     domainPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
2131     NetworkData::OnMeshPrefixConfig prefixConfig;
2132     uint16_t                        heapAllocations;
2133 
2134     Log("--------------------------------------------------------------------------------------------");
2135     Log("TestDomainPrefixAsOmr");
2136 
2137     InitTest();
2138 
2139     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2140     // Start Routing Manager. Check emitted RS and RA messages.
2141 
2142     sRsEmitted   = false;
2143     sRaValidated = false;
2144     sExpectedPio = kPioAdvertisingLocalOnLink;
2145     sExpectedRios.Clear();
2146 
2147     heapAllocations = sHeapAllocatedPtrs.GetLength();
2148     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2149 
2150     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2151     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2152 
2153     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2154     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2155 
2156     sExpectedRios.Add(localOmr);
2157 
2158     AdvanceTime(30000);
2159 
2160     VerifyOrQuit(sRsEmitted);
2161     VerifyOrQuit(sRaValidated);
2162     VerifyOrQuit(sExpectedRios.SawAll());
2163     Log("Received RA was validated");
2164 
2165     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2166     // Check Network Data to include the local OMR and on-link prefix.
2167 
2168     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2169     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2170 
2171     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2172     // Add a domain prefix directly into net data. The new prefix should
2173     // be favored over the local OMR prefix.
2174 
2175     otBackboneRouterSetEnabled(sInstance, true);
2176 
2177     prefixConfig.Clear();
2178     prefixConfig.mPrefix       = domainPrefix;
2179     prefixConfig.mStable       = true;
2180     prefixConfig.mSlaac        = true;
2181     prefixConfig.mPreferred    = true;
2182     prefixConfig.mOnMesh       = true;
2183     prefixConfig.mDefaultRoute = false;
2184     prefixConfig.mDp           = true;
2185     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
2186 
2187     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
2188     SuccessOrQuit(otBorderRouterRegister(sInstance));
2189 
2190     AdvanceTime(100);
2191 
2192     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2193     // Make sure BR emits RA without domain prefix or previous local OMR.
2194 
2195     sRaValidated = false;
2196     sExpectedPio = kPioAdvertisingLocalOnLink;
2197     sExpectedRios.Clear();
2198     sExpectedRios.Add(domainPrefix);
2199     sExpectedRios.Add(localOmr);
2200 
2201     AdvanceTime(20000);
2202 
2203     VerifyOrQuit(sRaValidated);
2204 
2205     // We should see RIO removing the local OMR prefix with lifetime zero
2206     // and should not see the domain prefix as RIO.
2207 
2208     VerifyOrQuit(sExpectedRios[0].mPrefix == domainPrefix);
2209     VerifyOrQuit(!sExpectedRios[0].mSawInRa);
2210 
2211     VerifyOrQuit(sExpectedRios[1].mPrefix == localOmr);
2212     VerifyOrQuit(sExpectedRios[1].mSawInRa);
2213     VerifyOrQuit(sExpectedRios[1].mLifetime <= kRioDeprecatingLifetime);
2214     VerifyOrQuit(sExpectedRios[1].mPreference == NetworkData::kRoutePreferenceLow);
2215 
2216     // Wait long enough for deprecating RIO prefix to expire
2217     AdvanceTime(3200000);
2218 
2219     sRaValidated = false;
2220     sExpectedPio = kPioAdvertisingLocalOnLink;
2221     sExpectedRios.Clear();
2222     sExpectedRios.Add(domainPrefix);
2223     sExpectedRios.Add(localOmr);
2224 
2225     // Wait for next RA (650 seconds).
2226 
2227     AdvanceTime(650000);
2228 
2229     VerifyOrQuit(sRaValidated);
2230 
2231     // We should not see either domain prefix or local OMR
2232     // as RIO.
2233 
2234     VerifyOrQuit(!sExpectedRios[0].mSawInRa);
2235     VerifyOrQuit(!sExpectedRios[1].mSawInRa);
2236 
2237     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2238     // Check Network Data. We should now see that the local OMR prefix
2239     // is removed.
2240 
2241     VerifyOmrPrefixInNetData(domainPrefix, /* aDefaultRoute */ false);
2242     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2243 
2244     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2245     // Remove the domain prefix from net data.
2246 
2247     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &domainPrefix));
2248     SuccessOrQuit(otBorderRouterRegister(sInstance));
2249 
2250     AdvanceTime(100);
2251 
2252     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2253     // Make sure BR emits RA with local OMR prefix again.
2254 
2255     sRaValidated = false;
2256     sExpectedRios.Clear();
2257     sExpectedRios.Add(localOmr);
2258 
2259     AdvanceTime(20000);
2260 
2261     VerifyOrQuit(sRaValidated);
2262     VerifyOrQuit(sExpectedRios.SawAll());
2263 
2264     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2265     // Check Network Data. We should see that the local OMR prefix is
2266     // added again.
2267 
2268     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2269     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2270 
2271     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2272 
2273     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2274     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2275 
2276     Log("End of TestDomainPrefixAsOmr");
2277     FinalizeTest();
2278 }
2279 #endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
2280 
TestExtPanIdChange(void)2281 void TestExtPanIdChange(void)
2282 {
2283     static constexpr uint32_t kMaxRaTxInterval = 196; // In seconds
2284 
2285     static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
2286     static const otExtendedPanId kExtPanId2 = {{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99, 0x88}};
2287     static const otExtendedPanId kExtPanId3 = {{0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xcd, 0xef}};
2288     static const otExtendedPanId kExtPanId4 = {{0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00}};
2289     static const otExtendedPanId kExtPanId5 = {{0x77, 0x88, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55}};
2290 
2291     Ip6::Prefix          localOnLink;
2292     Ip6::Prefix          oldLocalOnLink;
2293     Ip6::Prefix          localOmr;
2294     Ip6::Prefix          onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
2295     Ip6::Address         routerAddressA = AddressFromString("fd00::aaaa");
2296     uint32_t             oldPrefixLifetime;
2297     Ip6::Prefix          oldPrefixes[4];
2298     otOperationalDataset dataset;
2299     uint16_t             heapAllocations;
2300 
2301     Log("--------------------------------------------------------------------------------------------");
2302     Log("TestExtPanIdChange");
2303 
2304     InitTest();
2305 
2306     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2307     // Start Routing Manager. Check emitted RS and RA messages.
2308 
2309     heapAllocations = sHeapAllocatedPtrs.GetLength();
2310     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2311 
2312     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2313     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2314 
2315     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2316     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2317 
2318     sRsEmitted   = false;
2319     sRaValidated = false;
2320     sExpectedPio = kPioAdvertisingLocalOnLink;
2321     sExpectedRios.Clear();
2322     sExpectedRios.Add(localOmr);
2323 
2324     AdvanceTime(30000);
2325 
2326     VerifyOrQuit(sRsEmitted);
2327     VerifyOrQuit(sRaValidated);
2328     VerifyOrQuit(sExpectedRios.SawAll());
2329     Log("Local on-link prefix is being advertised, lifetime: %d", sOnLinkLifetime);
2330 
2331     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2332     // Check behavior when ext PAN ID changes while the local on-link is
2333     // being advertised.
2334 
2335     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2336     // Change the extended PAN ID.
2337 
2338     Log("Changing ext PAN ID");
2339 
2340     oldLocalOnLink    = localOnLink;
2341     oldPrefixLifetime = sOnLinkLifetime;
2342 
2343     sRaValidated = false;
2344     sExpectedPio = kPioAdvertisingLocalOnLink;
2345 
2346     SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
2347 
2348     VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
2349 
2350     dataset.mExtendedPanId = kExtPanId1;
2351     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2352 
2353     AdvanceTime(500);
2354     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2355     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
2356         oldLocalOnLink.ToString().AsCString());
2357 
2358     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2359     // Validate the received RA message and that it contains the
2360     // old on-link prefix being deprecated.
2361 
2362     AdvanceTime(30000);
2363 
2364     VerifyOrQuit(sRaValidated);
2365     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2366     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
2367     oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2368 
2369     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2370     // Validate Network Data.
2371 
2372     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2373     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2374 
2375     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2376     // Stop BR and validate that a final RA is emitted deprecating
2377     // both current local on-link prefix and old prefix.
2378 
2379     sRaValidated = false;
2380     sExpectedPio = kPioDeprecatingLocalOnLink;
2381 
2382     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2383     AdvanceTime(100);
2384 
2385     VerifyOrQuit(sRaValidated);
2386     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2387     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
2388     oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2389 
2390     sRaValidated = false;
2391     AdvanceTime(350000);
2392     VerifyOrQuit(!sRaValidated);
2393 
2394     VerifyNoOmrPrefixInNetData();
2395     VerifyExternalRouteInNetData(kNoRoute);
2396 
2397     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2398     // Start BR again and validate old prefix will continue to
2399     // be deprecated.
2400 
2401     sRaValidated = false;
2402     sExpectedPio = kPioAdvertisingLocalOnLink;
2403 
2404     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2405 
2406     AdvanceTime(300000);
2407     VerifyOrQuit(sRaValidated);
2408     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2409     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
2410     VerifyOrQuit(oldPrefixLifetime > sDeprecatingPrefixes[0].mLifetime);
2411     oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2412 
2413     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2414     // Wait for old local on-link prefix to expire.
2415 
2416     while (oldPrefixLifetime > 2 * kMaxRaTxInterval)
2417     {
2418         // Ensure Network Data entries remain as before.
2419 
2420         VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2421 
2422         // Keep checking the emitted RAs and make sure the prefix
2423         // is included with smaller lifetime every time.
2424 
2425         sRaValidated = false;
2426 
2427         AdvanceTime(kMaxRaTxInterval * 1000);
2428 
2429         VerifyOrQuit(sRaValidated);
2430         VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2431         Log("Old on-link prefix is deprecating, remaining lifetime:%d", sDeprecatingPrefixes[0].mLifetime);
2432         VerifyOrQuit(sDeprecatingPrefixes[0].mLifetime < oldPrefixLifetime);
2433         oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2434     }
2435 
2436     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2437     // The local on-link prefix must be expired now and should no
2438     // longer be seen in the emitted RA message.
2439 
2440     sRaValidated = false;
2441 
2442     AdvanceTime(3 * kMaxRaTxInterval * 1000);
2443 
2444     VerifyOrQuit(sRaValidated);
2445     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2446     Log("Old on-link prefix is now expired");
2447 
2448     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2449     // Validate the Network Data.
2450 
2451     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2452     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2453 
2454     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2455     // Check behavior when ext PAN ID changes while the local on-link is being
2456     // deprecated.
2457 
2458     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2459     // Send an RA from router A with a new on-link (PIO) which is preferred over
2460     // the local on-link prefix.
2461 
2462     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2463 
2464     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2465     // Validate that the local on-link prefix is deprecated.
2466 
2467     sRaValidated = false;
2468     sExpectedPio = kPioDeprecatingLocalOnLink;
2469 
2470     AdvanceTime(30000);
2471 
2472     VerifyOrQuit(sRaValidated);
2473 
2474     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2475     // Change the extended PAN ID.
2476 
2477     oldLocalOnLink    = localOnLink;
2478     oldPrefixLifetime = sOnLinkLifetime;
2479 
2480     dataset.mExtendedPanId = kExtPanId2;
2481     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2482 
2483     AdvanceTime(500);
2484     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2485     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
2486         oldLocalOnLink.ToString().AsCString());
2487 
2488     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2489     // Validate that the old local on-link prefix is still being included
2490     // as PIO in the emitted RA.
2491 
2492     sRaValidated = false;
2493     sExpectedPio = kNoPio;
2494 
2495     AdvanceTime(30000);
2496 
2497     VerifyOrQuit(sRaValidated);
2498     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2499     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
2500 
2501     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2502     // Validate that Network Data.
2503 
2504     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2505     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2506 
2507     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2508     // Wait for old local on-link prefix to expire.
2509 
2510     while (oldPrefixLifetime > 2 * kMaxRaTxInterval)
2511     {
2512         // Send same RA from router A to keep its on-link prefix alive.
2513 
2514         SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2515 
2516         // Ensure Network Data entries remain as before.
2517 
2518         VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2519 
2520         // Keep checking the emitted RAs and make sure the prefix
2521         // is included with smaller lifetime every time.
2522 
2523         sRaValidated = false;
2524 
2525         AdvanceTime(kMaxRaTxInterval * 1000);
2526 
2527         VerifyOrQuit(sRaValidated);
2528         VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2529         Log("Old on-link prefix is deprecating, remaining lifetime:%d", sDeprecatingPrefixes[0].mLifetime);
2530         VerifyOrQuit(sDeprecatingPrefixes[0].mLifetime < oldPrefixLifetime);
2531         oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2532     }
2533 
2534     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2535     // The old on-link prefix must be expired now and should no
2536     // longer be seen in the emitted RA message.
2537 
2538     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2539 
2540     sRaValidated = false;
2541 
2542     AdvanceTime(kMaxRaTxInterval * 1000);
2543     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2544     AdvanceTime(kMaxRaTxInterval * 1000);
2545     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2546     AdvanceTime(kMaxRaTxInterval * 1000);
2547 
2548     VerifyOrQuit(sRaValidated);
2549     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2550     Log("Old on-link prefix is now expired");
2551 
2552     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2553     // Validate the Network Data.
2554 
2555     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2556     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2557 
2558     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2559     // Check behavior when ext PAN ID changes while the local on-link is not
2560     // advertised.
2561 
2562     Log("Changing ext PAN ID again");
2563 
2564     oldLocalOnLink = localOnLink;
2565 
2566     sRaValidated = false;
2567     sExpectedPio = kNoPio;
2568 
2569     dataset.mExtendedPanId = kExtPanId3;
2570     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2571 
2572     AdvanceTime(500);
2573     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2574     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
2575         oldLocalOnLink.ToString().AsCString());
2576 
2577     AdvanceTime(35000);
2578     VerifyOrQuit(sRaValidated);
2579     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2580 
2581     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2582     // Validate the Network Data.
2583 
2584     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2585     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2586 
2587     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2588     // Remove the on-link prefix PIO being advertised by router A
2589     // and ensure local on-link prefix is advertised again.
2590 
2591     sRaValidated = false;
2592     sExpectedPio = kPioAdvertisingLocalOnLink;
2593 
2594     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, 0)});
2595 
2596     AdvanceTime(300000);
2597     VerifyOrQuit(sRaValidated);
2598     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2599 
2600     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2601     // Wait for longer than valid lifetime of PIO entry from router A.
2602     // Validate that default route is unpublished from network data.
2603 
2604     AdvanceTime(2000 * 1000);
2605     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2606     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2607 
2608     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2609     // Multiple PAN ID changes and multiple deprecating old prefixes.
2610 
2611     oldPrefixes[0] = localOnLink;
2612 
2613     dataset.mExtendedPanId = kExtPanId2;
2614     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2615 
2616     sRaValidated = false;
2617     sExpectedPio = kPioAdvertisingLocalOnLink;
2618 
2619     AdvanceTime(30000);
2620     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2621     VerifyOrQuit(sRaValidated);
2622     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2623     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2624 
2625     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2626 
2627     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2628     // Change the prefix again. We should see two deprecating prefixes.
2629 
2630     oldPrefixes[1] = localOnLink;
2631 
2632     dataset.mExtendedPanId = kExtPanId1;
2633     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2634 
2635     sRaValidated = false;
2636     sExpectedPio = kPioAdvertisingLocalOnLink;
2637 
2638     AdvanceTime(30000);
2639     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2640     VerifyOrQuit(sRaValidated);
2641     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 2);
2642     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2643     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2644 
2645     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2646 
2647     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2648     // Wait for 15 minutes and then change ext PAN ID again.
2649     // Now we should see three deprecating prefixes.
2650 
2651     AdvanceTime(15 * 60 * 1000);
2652 
2653     oldPrefixes[2] = localOnLink;
2654 
2655     dataset.mExtendedPanId = kExtPanId4;
2656     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2657 
2658     sRaValidated = false;
2659     sExpectedPio = kPioAdvertisingLocalOnLink;
2660 
2661     AdvanceTime(30000);
2662     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2663     VerifyOrQuit(sRaValidated);
2664     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2665     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2666     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2667     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[2]));
2668 
2669     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2670 
2671     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2672     // Change ext PAN ID back to previous value of `kExtPanId1`.
2673     // We should still see three deprecating prefixes and the last prefix
2674     // at `oldPrefixes[2]` should again be treated as local on-link prefix.
2675 
2676     oldPrefixes[3] = localOnLink;
2677 
2678     dataset.mExtendedPanId = kExtPanId1;
2679     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2680 
2681     sRaValidated = false;
2682     sExpectedPio = kPioAdvertisingLocalOnLink;
2683 
2684     AdvanceTime(30000);
2685     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2686     VerifyOrQuit(sRaValidated);
2687     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2688     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2689     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2690     VerifyOrQuit(oldPrefixes[2] == localOnLink);
2691     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[3]));
2692 
2693     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2694 
2695     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2696     // Stop BR and validate the final emitted RA to contain
2697     // all deprecating prefixes.
2698 
2699     sRaValidated = false;
2700     sExpectedPio = kPioDeprecatingLocalOnLink;
2701 
2702     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2703     AdvanceTime(100);
2704 
2705     VerifyOrQuit(sRaValidated);
2706     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2707     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2708     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2709     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[3]));
2710 
2711     VerifyNoOmrPrefixInNetData();
2712     VerifyExternalRouteInNetData(kNoRoute);
2713 
2714     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2715     // Wait for 15 minutes while BR stays disabled and validate
2716     // there are no emitted RAs. We want to check that deprecating
2717     // prefixes continue to expire while BR is stopped.
2718 
2719     sRaValidated = false;
2720     AdvanceTime(15 * 60 * 1000);
2721 
2722     VerifyOrQuit(!sRaValidated);
2723 
2724     VerifyNoOmrPrefixInNetData();
2725     VerifyExternalRouteInNetData(kNoRoute);
2726 
2727     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2728     // Start BR again, and check that we only see the last deprecating prefix
2729     // at `oldPrefixes[3]` in emitted RA and the other two are expired and
2730     // no longer included as PIO and/or in network data.
2731 
2732     sRaValidated = false;
2733     sExpectedPio = kPioAdvertisingLocalOnLink;
2734 
2735     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2736 
2737     AdvanceTime(30000);
2738 
2739     VerifyOrQuit(sRaValidated);
2740     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2741     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[3]));
2742 
2743     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2744 
2745     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2746     // Validate the oldest prefix is removed when we have too many
2747     // back-to-back PAN ID changes.
2748 
2749     // Remember the oldest deprecating prefix (associated with `kExtPanId4`).
2750     oldLocalOnLink = oldPrefixes[3];
2751 
2752     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(oldPrefixes[0]));
2753     dataset.mExtendedPanId = kExtPanId2;
2754     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2755     AdvanceTime(30000);
2756 
2757     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(oldPrefixes[1]));
2758     dataset.mExtendedPanId = kExtPanId3;
2759     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2760     AdvanceTime(30000);
2761 
2762     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(oldPrefixes[2]));
2763     dataset.mExtendedPanId = kExtPanId5;
2764     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2765 
2766     sRaValidated = false;
2767 
2768     AdvanceTime(30000);
2769 
2770     VerifyOrQuit(sRaValidated);
2771     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2772     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2773     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2774     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2775     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[2]));
2776     VerifyOrQuit(!sDeprecatingPrefixes.ContainsMatching(oldLocalOnLink));
2777 
2778     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2779 
2780     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2781 
2782     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2783     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2784 
2785     Log("End of TestExtPanIdChange");
2786     FinalizeTest();
2787 }
2788 
TestPrefixStaleTime(void)2789 void TestPrefixStaleTime(void)
2790 {
2791     Ip6::Prefix  localOnLink;
2792     Ip6::Prefix  localOmr;
2793     Ip6::Prefix  onLinkPrefixA  = PrefixFromString("2000:abba:baba:aaaa::", 64);
2794     Ip6::Prefix  onLinkPrefixB  = PrefixFromString("2000:abba:baba:bbbb::", 64);
2795     Ip6::Prefix  routePrefix    = PrefixFromString("2000:1234:5678::", 64);
2796     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
2797     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
2798     uint16_t     heapAllocations;
2799 
2800     Log("--------------------------------------------------------------------------------------------");
2801     Log("TestPrefixStaleTime");
2802 
2803     InitTest();
2804 
2805     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2806     // Start Routing Manager. Check emitted RS and RA messages.
2807 
2808     sRsEmitted   = false;
2809     sRaValidated = false;
2810     sExpectedPio = kPioAdvertisingLocalOnLink;
2811     sExpectedRios.Clear();
2812 
2813     heapAllocations = sHeapAllocatedPtrs.GetLength();
2814     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2815 
2816     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2817     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2818 
2819     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2820     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2821 
2822     sExpectedRios.Add(localOmr);
2823 
2824     AdvanceTime(30000);
2825 
2826     VerifyOrQuit(sRsEmitted);
2827     VerifyOrQuit(sRaValidated);
2828     VerifyOrQuit(sExpectedRios.SawAll());
2829     Log("Received RA was validated");
2830 
2831     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2832     // Advertise a route prefix with 200 seconds lifetime from router A.
2833     // Advertise the same route prefix with 800 seconds lifetime from
2834     // router B.
2835 
2836     SendRouterAdvert(routerAddressA, {Rio(routePrefix, 200, NetworkData::kRoutePreferenceMedium)});
2837     SendRouterAdvert(routerAddressB, {Rio(routePrefix, 800, NetworkData::kRoutePreferenceMedium)});
2838 
2839     AdvanceTime(10);
2840 
2841     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2842     // Check the discovered prefix table and ensure info from router A and B
2843     // is present in the table.
2844 
2845     VerifyPrefixTable({RoutePrefix(routePrefix, 200, NetworkData::kRoutePreferenceMedium, routerAddressA),
2846                        RoutePrefix(routePrefix, 800, NetworkData::kRoutePreferenceMedium, routerAddressB)});
2847 
2848     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2849     // Wait for a period exceeding the 200-second lifetime of the route
2850     // advertised by router A. Confirm that the stale timer does not expire
2851     // during this time, and no RS messages sent. This verifies that the
2852     // presence of the matching entry from router B successfully extended
2853     // the stale time for the route prefix.
2854 
2855     sRsEmitted = false;
2856 
2857     AdvanceTime(590 * 1000);
2858 
2859     VerifyOrQuit(!sRsEmitted);
2860 
2861     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2862     // Check the discovered prefix table and ensure router A entry is
2863     // expired and removed.
2864 
2865     VerifyPrefixTable({RoutePrefix(routePrefix, 800, NetworkData::kRoutePreferenceMedium, routerAddressB)});
2866 
2867     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2868     // Wait for the 600-second stale time to expire. This is shorter
2869     // than the 800-second lifetime of the prefix advertised by
2870     // Router B, so the 600-second value will be used. We should now
2871     // observe RS messages being transmitted.
2872 
2873     AdvanceTime(20 * 1000);
2874 
2875     VerifyOrQuit(sRsEmitted);
2876 
2877     VerifyPrefixTableIsEmpty();
2878 
2879     AdvanceTime(5 * 000);
2880 
2881     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2882     // Advertise the same on-link prefix A with different lifetimes from routers A and B.
2883     // Advertise a different on-link prefix from router A.
2884 
2885     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefixA, 1800, 200), Pio(onLinkPrefixB, 2000, 2000)});
2886     SendRouterAdvert(routerAddressB, {Pio(onLinkPrefixA, 1800, 500)});
2887 
2888     AdvanceTime(10);
2889 
2890     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2891     // Check the discovered prefix table and ensure info from router A and B
2892     // is present in the table.
2893 
2894     VerifyPrefixTable({OnLinkPrefix(onLinkPrefixA, 1800, 200, routerAddressA),
2895                        OnLinkPrefix(onLinkPrefixB, 2000, 2000, routerAddressA),
2896                        OnLinkPrefix(onLinkPrefixA, 1800, 500, routerAddressB)});
2897 
2898     sRsEmitted = false;
2899 
2900     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2901     // Wait for a period exceeding the 200-second lifetime of the on-link prefix.
2902     // Confirm stale timer is not expired and no RS is emitted.
2903 
2904     sRsEmitted = false;
2905 
2906     AdvanceTime(490 * 1000);
2907 
2908     VerifyOrQuit(!sRsEmitted);
2909 
2910     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2911     // Wait for a 500-second lifetime for prefix advertised by router B. Now
2912     // we should see RS messages emitted.
2913 
2914     AdvanceTime(20 * 1000);
2915 
2916     VerifyOrQuit(sRsEmitted);
2917 
2918     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2919 
2920     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2921     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2922 
2923     Log("End of TestPrefixStaleTime");
2924     FinalizeTest();
2925 }
2926 
TestRouterNsProbe(void)2927 void TestRouterNsProbe(void)
2928 {
2929     Ip6::Prefix  localOnLink;
2930     Ip6::Prefix  localOmr;
2931     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
2932     Ip6::Prefix  routePrefix    = PrefixFromString("2000:1234:5678::", 64);
2933     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
2934     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
2935     uint16_t     heapAllocations;
2936 
2937     Log("--------------------------------------------------------------------------------------------");
2938     Log("TestRouterNsProbe");
2939 
2940     InitTest();
2941 
2942     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2943     // Start Routing Manager. Check emitted RS and RA messages.
2944 
2945     sRsEmitted   = false;
2946     sRaValidated = false;
2947     sExpectedPio = kPioAdvertisingLocalOnLink;
2948     sExpectedRios.Clear();
2949 
2950     heapAllocations = sHeapAllocatedPtrs.GetLength();
2951     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2952 
2953     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2954     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2955 
2956     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2957     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2958 
2959     sExpectedRios.Add(localOmr);
2960 
2961     AdvanceTime(30000);
2962 
2963     VerifyOrQuit(sRsEmitted);
2964     VerifyOrQuit(sRaValidated);
2965     VerifyOrQuit(sExpectedRios.SawAll());
2966     Log("Received RA was validated");
2967 
2968     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2969     // Send an RA from router A with a new on-link (PIO) and route prefix (RIO).
2970 
2971     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
2972                      {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
2973 
2974     sExpectedPio = kPioDeprecatingLocalOnLink;
2975 
2976     AdvanceTime(10);
2977 
2978     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2979     // Check the discovered prefix table and ensure info from router A
2980     // is present in the table.
2981 
2982     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
2983                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
2984 
2985     AdvanceTime(30000);
2986 
2987     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2988     // Send an RA from router B with same route prefix (RIO) but with
2989     // high route preference.
2990 
2991     SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
2992 
2993     AdvanceTime(200);
2994 
2995     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2996     // Check the discovered prefix table and ensure entries from
2997     // both router A and B are seen.
2998 
2999     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
3000                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA),
3001                        RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
3002 
3003     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3004     // Check that BR emitted an NS to ensure routers are active.
3005 
3006     sNsEmitted = false;
3007     sRsEmitted = false;
3008 
3009     AdvanceTime(160 * 1000);
3010 
3011     VerifyOrQuit(sNsEmitted);
3012     VerifyOrQuit(!sRsEmitted);
3013 
3014     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3015     // Disallow responding to NS message.
3016     //
3017     // This should trigger `RoutingManager` to send RS (which will get
3018     // no response as well) and then remove all router entries.
3019 
3020     sRespondToNs = false;
3021 
3022     sExpectedPio = kPioAdvertisingLocalOnLink;
3023     sRaValidated = false;
3024     sNsEmitted   = false;
3025 
3026     AdvanceTime(240 * 1000);
3027 
3028     VerifyOrQuit(sNsEmitted);
3029     VerifyOrQuit(sRaValidated);
3030 
3031     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3032     // Check the discovered prefix table. We should see the on-link entry from
3033     // router A as deprecated and no route prefix.
3034 
3035     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, 0, routerAddressA)});
3036 
3037     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3038     // Verify that no more NS is being sent (since there is no more valid
3039     // router entry in the table).
3040 
3041     sExpectedPio = kPioAdvertisingLocalOnLink;
3042     sRaValidated = false;
3043     sNsEmitted   = false;
3044 
3045     AdvanceTime(6 * 60 * 1000);
3046 
3047     VerifyOrQuit(!sNsEmitted);
3048 
3049     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3050     // Send an RA from router B and verify that we see router B
3051     // entry in prefix table.
3052 
3053     SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
3054 
3055     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, 0, routerAddressA)},
3056                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
3057 
3058     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3059     // Wait for longer than router active time before NS probe.
3060     // Check again that NS are sent again.
3061 
3062     sRespondToNs = true;
3063     sNsEmitted   = false;
3064     sRsEmitted   = false;
3065 
3066     AdvanceTime(3 * 60 * 1000);
3067 
3068     VerifyOrQuit(sNsEmitted);
3069     VerifyOrQuit(!sRsEmitted);
3070 
3071     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3072 
3073     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
3074     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
3075 
3076     Log("End of TestRouterNsProbe");
3077     FinalizeTest();
3078 }
3079 
TestLearningAndCopyingOfFlags(void)3080 void TestLearningAndCopyingOfFlags(void)
3081 {
3082     Ip6::Prefix  localOnLink;
3083     Ip6::Prefix  localOmr;
3084     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
3085     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
3086     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
3087     Ip6::Address routerAddressC = AddressFromString("fd00::cccc");
3088     uint16_t     heapAllocations;
3089     RaFlags      raFlags;
3090 
3091     Log("--------------------------------------------------------------------------------------------");
3092     Log("TestLearningAndCopyingOfFlags");
3093 
3094     InitTest();
3095 
3096     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3097     // Start Routing Manager. Check emitted RS and RA messages.
3098 
3099     sRsEmitted   = false;
3100     sRaValidated = false;
3101     sExpectedPio = kPioAdvertisingLocalOnLink;
3102     sExpectedRios.Clear();
3103 
3104     heapAllocations = sHeapAllocatedPtrs.GetLength();
3105     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3106 
3107     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3108     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3109 
3110     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3111     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3112 
3113     sExpectedRios.Add(localOmr);
3114 
3115     AdvanceTime(30000);
3116 
3117     VerifyOrQuit(sRsEmitted);
3118     VerifyOrQuit(sRaValidated);
3119     VerifyOrQuit(sExpectedRios.SawAll());
3120     Log("Received RA was validated");
3121 
3122     VerifyDiscoveredRoutersIsEmpty();
3123 
3124     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3125     // Send an RA from router A with M flag set, and make sure the
3126     // emitted RA from BR also includes M flag.
3127 
3128     raFlags.Clear();
3129     raFlags.mManagedAddressConfigFlag = true;
3130 
3131     SendRouterAdvert(routerAddressA, raFlags);
3132 
3133     AdvanceTime(1);
3134     VerifyDiscoveredRouters({InfraRouter(routerAddressA, /* M */ true, /* O */ false, /* StubRouter */ false)});
3135 
3136     sRaValidated           = false;
3137     sExpectedRaHeaderFlags = kRaHeaderFlagsOnlyM;
3138 
3139     AdvanceTime(310 * 1000);
3140     VerifyOrQuit(sRaValidated);
3141 
3142     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3143     // Send an RA from router A without the M flag. Now the emitted
3144     // RA should no longer contain the M flag.
3145 
3146     raFlags.Clear();
3147 
3148     SendRouterAdvert(routerAddressA, raFlags);
3149 
3150     sRaValidated           = false;
3151     sExpectedRaHeaderFlags = kRaHeaderFlagsNone;
3152 
3153     AdvanceTime(1);
3154     VerifyDiscoveredRoutersIsEmpty();
3155 
3156     AdvanceTime(310 * 1000);
3157     VerifyOrQuit(sRaValidated);
3158 
3159     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3160     // Send an RA from router A with both M and StubRouter flags.
3161     // Since it is from a stub router, the M flag should be ignored.
3162     // Ensure emitted RA does not set the M flag.
3163 
3164     raFlags.Clear();
3165     raFlags.mManagedAddressConfigFlag = true;
3166     raFlags.mStubRouterFlag           = true;
3167 
3168     SendRouterAdvert(routerAddressA, raFlags);
3169 
3170     AdvanceTime(1);
3171     VerifyDiscoveredRouters({InfraRouter(routerAddressA, /* M */ true, /* O */ false, /* StubRouter */ true)});
3172 
3173     sRaValidated           = false;
3174     sExpectedRaHeaderFlags = kRaHeaderFlagsNone;
3175 
3176     AdvanceTime(310 * 1000);
3177     VerifyOrQuit(sRaValidated);
3178 
3179     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3180     // Send an RA from router B with O flag and check that emitted
3181     // RA include the same flag.
3182 
3183     raFlags.Clear();
3184     raFlags.mOtherConfigFlag = true;
3185 
3186     SendRouterAdvert(routerAddressB, raFlags);
3187 
3188     AdvanceTime(1);
3189     VerifyDiscoveredRouters({InfraRouter(routerAddressA, /* M */ true, /* O */ false, /* StubRouter */ true),
3190                              InfraRouter(routerAddressB, /* M */ false, /* O */ true, /* StubRouter */ false)});
3191 
3192     sRaValidated           = false;
3193     sExpectedRaHeaderFlags = kRaHeaderFlagsOnlyO;
3194 
3195     AdvanceTime(310 * 1000);
3196     VerifyOrQuit(sRaValidated);
3197 
3198     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3199     // Send an RA from router C with M flag and check that emitted
3200     // RA now includes both M and O flags.
3201 
3202     raFlags.Clear();
3203     raFlags.mManagedAddressConfigFlag = true;
3204 
3205     SendRouterAdvert(routerAddressC, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
3206                      DefaultRoute(0, NetworkData::kRoutePreferenceMedium), raFlags);
3207 
3208     AdvanceTime(1);
3209     VerifyDiscoveredRouters({InfraRouter(routerAddressA, /* M */ true, /* O */ false, /* StubRouter */ true),
3210                              InfraRouter(routerAddressB, /* M */ false, /* O */ true, /* StubRouter */ false),
3211                              InfraRouter(routerAddressC, /* M */ true, /* O */ false, /* StubRouter */ false)});
3212 
3213     sRaValidated           = false;
3214     sExpectedPio           = kPioDeprecatingLocalOnLink;
3215     sExpectedRaHeaderFlags = kRaHeaderFlagsBothMAndO;
3216 
3217     AdvanceTime(310 * 1000);
3218     VerifyOrQuit(sRaValidated);
3219 
3220     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3221     // Stop responding to NS, this should cause all routers
3222     // to age and considered offline
3223 
3224     sRespondToNs = false;
3225 
3226     sExpectedRaHeaderFlags = kRaHeaderFlagsSkipChecking;
3227 
3228     AdvanceTime(300 * 1000);
3229 
3230     // Router C should be in the table since it will have a deprecating
3231     // on-link prefix.
3232     VerifyDiscoveredRouters({InfraRouter(routerAddressC, /* M */ true, /* O */ false, /* StubRouter */ false)});
3233 
3234     sRaValidated           = false;
3235     sExpectedPio           = kPioAdvertisingLocalOnLink;
3236     sExpectedRaHeaderFlags = kRaHeaderFlagsNone;
3237 
3238     AdvanceTime(610 * 1000);
3239     VerifyOrQuit(sRaValidated);
3240 
3241     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3242 
3243     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
3244     VerifyDiscoveredRoutersIsEmpty();
3245 
3246     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
3247 
3248     Log("End of TestLearningAndCopyingOfFlags");
3249     FinalizeTest();
3250 }
3251 
TestLearnRaHeader(void)3252 void TestLearnRaHeader(void)
3253 {
3254     Ip6::Prefix localOnLink;
3255     Ip6::Prefix localOmr;
3256     Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
3257     uint16_t    heapAllocations;
3258 
3259     Log("--------------------------------------------------------------------------------------------");
3260     Log("TestLearnRaHeader");
3261 
3262     InitTest();
3263 
3264     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3265     // Start Routing Manager. Check emitted RS and RA messages.
3266 
3267     sRsEmitted   = false;
3268     sRaValidated = false;
3269     sExpectedPio = kPioAdvertisingLocalOnLink;
3270     sExpectedRios.Clear();
3271 
3272     heapAllocations = sHeapAllocatedPtrs.GetLength();
3273     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3274 
3275     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3276     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3277 
3278     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3279     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3280 
3281     sExpectedRios.Add(localOmr);
3282 
3283     AdvanceTime(30000);
3284 
3285     VerifyOrQuit(sRsEmitted);
3286     VerifyOrQuit(sRaValidated);
3287     VerifyOrQuit(sExpectedRios.SawAll());
3288     Log("Received RA was validated");
3289 
3290     VerifyDiscoveredRoutersIsEmpty();
3291 
3292     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3293     // Send an RA from the same address (another entity on the device)
3294     // advertising a default route.
3295 
3296     SendRouterAdvert(sInfraIfAddress, DefaultRoute(1000, NetworkData::kRoutePreferenceLow));
3297 
3298     AdvanceTime(1);
3299     VerifyDiscoveredRouters(
3300         {InfraRouter(sInfraIfAddress, /* M */ false, /* O */ false, /* StubRouter */ false, /* IsLocalDevice */ true)});
3301 
3302     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3303     // RoutingManager should learn the header from the
3304     // received RA (from same address) and start advertising
3305     // the same default route lifetime in the emitted RAs.
3306 
3307     sRaValidated              = false;
3308     sCheckRaHeaderLifetime    = true;
3309     sExpectedRaHeaderLifetime = 1000;
3310 
3311     AdvanceTime(30 * 1000);
3312     VerifyOrQuit(sRaValidated);
3313 
3314     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3315     // Wait for longer than entry lifetime (for it to expire) and
3316     // make sure `RoutingManager` stops advertising default route.
3317 
3318     sCheckRaHeaderLifetime = false;
3319 
3320     AdvanceTime(1000 * 1000);
3321 
3322     sRaValidated              = false;
3323     sCheckRaHeaderLifetime    = true;
3324     sExpectedRaHeaderLifetime = 0;
3325 
3326     AdvanceTime(700 * 1000);
3327     VerifyOrQuit(sRaValidated);
3328 
3329     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3330 
3331     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
3332     VerifyDiscoveredRoutersIsEmpty();
3333 
3334     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
3335 
3336     Log("End of TestLearnRaHeader");
3337     FinalizeTest();
3338 }
3339 
TestConflictingPrefix(void)3340 void TestConflictingPrefix(void)
3341 {
3342     static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
3343 
3344     Ip6::Prefix          localOnLink;
3345     Ip6::Prefix          oldLocalOnLink;
3346     Ip6::Prefix          localOmr;
3347     Ip6::Prefix          onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
3348     Ip6::Address         routerAddressA = AddressFromString("fd00::aaaa");
3349     Ip6::Address         routerAddressB = AddressFromString("fd00::bbbb");
3350     otOperationalDataset dataset;
3351     uint16_t             heapAllocations;
3352 
3353     Log("--------------------------------------------------------------------------------------------");
3354     Log("TestConflictingPrefix");
3355 
3356     InitTest();
3357 
3358     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3359     // Start Routing Manager. Check emitted RS and RA messages.
3360 
3361     sRsEmitted   = false;
3362     sRaValidated = false;
3363     sExpectedPio = kPioAdvertisingLocalOnLink;
3364     sExpectedRios.Clear();
3365 
3366     heapAllocations = sHeapAllocatedPtrs.GetLength();
3367     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3368 
3369     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3370     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3371 
3372     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3373     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3374 
3375     sExpectedRios.Add(localOmr);
3376 
3377     AdvanceTime(30000);
3378 
3379     VerifyOrQuit(sRsEmitted);
3380     VerifyOrQuit(sRaValidated);
3381     VerifyOrQuit(sExpectedRios.SawAll());
3382     Log("Received RA was validated");
3383 
3384     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3385     // Check Network Data to include the local OMR and on-link prefix.
3386 
3387     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3388     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3389 
3390     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3391     // Send an RA from router A with our local on-link prefix as RIO.
3392 
3393     Log("Send RA from router A with local on-link as RIO");
3394     SendRouterAdvert(routerAddressA, {Rio(localOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
3395 
3396     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3397     // Check that the local on-link prefix is still being advertised.
3398 
3399     sRaValidated = false;
3400     AdvanceTime(310000);
3401     VerifyOrQuit(sRaValidated);
3402 
3403     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3404     // Check Network Data to still include the local OMR and ULA prefix.
3405 
3406     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3407     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3408 
3409     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3410     // Send an RA from router A removing local on-link prefix as RIO.
3411 
3412     SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
3413 
3414     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3415     // Verify that ULA prefix is still included in Network Data and
3416     // the change by router A did not cause it to be unpublished.
3417 
3418     AdvanceTime(10000);
3419     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3420 
3421     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3422     // Check that the local on-link prefix is still being advertised.
3423 
3424     sRaValidated = false;
3425     AdvanceTime(310000);
3426     VerifyOrQuit(sRaValidated);
3427 
3428     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3429 
3430     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3431     // Send RA from router B advertising an on-link prefix. This
3432     // should cause local on-link prefix to be deprecated.
3433 
3434     SendRouterAdvert(routerAddressB, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3435 
3436     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3437     // Check that the local on-link prefix is now deprecating.
3438 
3439     sRaValidated = false;
3440     sExpectedPio = kPioDeprecatingLocalOnLink;
3441 
3442     AdvanceTime(10000);
3443     VerifyOrQuit(sRaValidated);
3444     VerifyOrQuit(sExpectedRios.SawAll());
3445     Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
3446 
3447     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3448     // Check Network Data to include the default route now due
3449     // the new on-link prefix from router B.
3450 
3451     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
3452     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3453 
3454     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3455     // Send an RA from router A again adding local on-link prefix as RIO.
3456 
3457     Log("Send RA from router A with local on-link as RIO");
3458     SendRouterAdvert(routerAddressA, {Rio(localOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
3459 
3460     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3461     // Check that the local on-link prefix is still being deprecated.
3462 
3463     sRaValidated = false;
3464     AdvanceTime(310000);
3465     VerifyOrQuit(sRaValidated);
3466 
3467     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3468     // Check Network Data remains unchanged.
3469 
3470     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3471 
3472     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3473     // Send an RA from router A removing the previous RIO.
3474 
3475     SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
3476 
3477     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3478     // Check Network Data remains unchanged.
3479 
3480     AdvanceTime(60000);
3481     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3482 
3483     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3484     // Send RA from router B removing its on-link prefix.
3485 
3486     SendRouterAdvert(routerAddressB, {Pio(onLinkPrefix, kValidLitime, 0)});
3487 
3488     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3489     // Check that the local on-link prefix is once again being advertised.
3490 
3491     sRaValidated = false;
3492     sExpectedPio = kPioAdvertisingLocalOnLink;
3493 
3494     AdvanceTime(10000);
3495     VerifyOrQuit(sRaValidated);
3496 
3497     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3498     // Check Network Data to remain unchanged.
3499 
3500     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3501 
3502     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3503     // Change the extended PAN ID.
3504 
3505     Log("Changing ext PAN ID");
3506 
3507     SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
3508 
3509     VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
3510 
3511     dataset.mExtendedPanId = kExtPanId1;
3512     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
3513     AdvanceTime(10000);
3514 
3515     oldLocalOnLink = localOnLink;
3516     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3517 
3518     Log("Local on-link prefix is changed to %s from %s", localOnLink.ToString().AsCString(),
3519         oldLocalOnLink.ToString().AsCString());
3520 
3521     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3522     // Check Network Data contains default route due to the
3523     // deprecating on-link prefix from router B.
3524 
3525     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3526 
3527     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3528     // Send an RA from router A again adding the old local on-link prefix
3529     // as RIO.
3530 
3531     SendRouterAdvert(routerAddressA, {Rio(oldLocalOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
3532 
3533     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3534     // Check Network Data remains unchanged.
3535 
3536     AdvanceTime(10000);
3537     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3538 
3539     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3540     // Send an RA from router A removing the previous RIO.
3541 
3542     SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
3543 
3544     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3545     // Check Network Data remains unchanged.
3546 
3547     AdvanceTime(10000);
3548     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3549 
3550     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3551 
3552     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
3553     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
3554 
3555     Log("End of TestConflictingPrefix");
3556 
3557     FinalizeTest();
3558 }
3559 
3560 #if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
TestSavedOnLinkPrefixes(void)3561 void TestSavedOnLinkPrefixes(void)
3562 {
3563     static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
3564 
3565     Ip6::Prefix          localOnLink;
3566     Ip6::Prefix          oldLocalOnLink;
3567     Ip6::Prefix          localOmr;
3568     Ip6::Prefix          onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
3569     Ip6::Address         routerAddressA = AddressFromString("fd00::aaaa");
3570     otOperationalDataset dataset;
3571 
3572     Log("--------------------------------------------------------------------------------------------");
3573     Log("TestSavedOnLinkPrefixes");
3574 
3575     InitTest(/* aEnablBorderRouting */ true);
3576 
3577     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3578     // Check emitted RS and RA messages.
3579 
3580     sRsEmitted   = false;
3581     sRaValidated = false;
3582     sExpectedPio = kPioAdvertisingLocalOnLink;
3583     sExpectedRios.Clear();
3584 
3585     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3586     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3587 
3588     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3589     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3590 
3591     sExpectedRios.Add(localOmr);
3592 
3593     AdvanceTime(30000);
3594 
3595     VerifyOrQuit(sRsEmitted);
3596     VerifyOrQuit(sRaValidated);
3597     VerifyOrQuit(sExpectedRios.SawAll());
3598 
3599     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3600     // Check Network Data to include the local OMR and ULA prefix.
3601 
3602     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3603     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3604 
3605     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3606     // Disable the instance and re-enable it.
3607 
3608     Log("Disabling and re-enabling OT Instance");
3609 
3610     testFreeInstance(sInstance);
3611 
3612     InitTest(/* aEnablBorderRouting */ true, /* aAfterReset */ true);
3613 
3614     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3615 
3616     sExpectedPio = kPioAdvertisingLocalOnLink;
3617 
3618     AdvanceTime(30000);
3619 
3620     VerifyOrQuit(sRsEmitted);
3621     VerifyOrQuit(sRaValidated);
3622     VerifyOrQuit(sExpectedRios.SawAll());
3623 
3624     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3625     // Check Network Data to include the local OMR and ULA prefix.
3626 
3627     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3628     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3629 
3630     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3631     // Send RA from router A advertising an on-link prefix.
3632 
3633     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3634 
3635     sRaValidated = false;
3636     sExpectedPio = kPioDeprecatingLocalOnLink;
3637 
3638     AdvanceTime(30000);
3639 
3640     VerifyOrQuit(sRaValidated);
3641     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 0);
3642 
3643     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3644     // Disable the instance and re-enable it.
3645 
3646     Log("Disabling and re-enabling OT Instance");
3647 
3648     testFreeInstance(sInstance);
3649 
3650     InitTest(/* aEnablBorderRouting */ true, /* aAfterReset */ true);
3651 
3652     sExpectedPio = kPioAdvertisingLocalOnLink;
3653 
3654     AdvanceTime(30000);
3655 
3656     VerifyOrQuit(sRsEmitted);
3657     VerifyOrQuit(sRaValidated);
3658     VerifyOrQuit(sExpectedRios.SawAll());
3659 
3660     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3661     // Check Network Data to include the local OMR and ULA prefix.
3662 
3663     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3664     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
3665 
3666     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3667 
3668     Log("Changing ext PAN ID");
3669 
3670     oldLocalOnLink = localOnLink;
3671 
3672     sRaValidated = false;
3673     sExpectedPio = kPioAdvertisingLocalOnLink;
3674 
3675     SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
3676 
3677     VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
3678 
3679     dataset.mExtendedPanId = kExtPanId1;
3680     dataset.mActiveTimestamp.mSeconds++;
3681     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
3682 
3683     AdvanceTime(30000);
3684 
3685     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3686     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
3687         oldLocalOnLink.ToString().AsCString());
3688 
3689     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3690     // Disable the instance and re-enable it.
3691 
3692     Log("Disabling and re-enabling OT Instance");
3693 
3694     testFreeInstance(sInstance);
3695 
3696     InitTest(/* aEnablBorderRouting */ false, /* aAfterReset */ true);
3697 
3698     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3699     // Start Routing Manager.
3700 
3701     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3702 
3703     AdvanceTime(100);
3704 
3705     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3706     // Send RA from router A advertising an on-link prefix.
3707     // This ensures the local on-link prefix is not advertised, but
3708     // it must be deprecated since it was advertised last time and
3709     // saved in `Settings`.
3710 
3711     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3712 
3713     sRaValidated = false;
3714     sExpectedPio = kPioDeprecatingLocalOnLink;
3715 
3716     AdvanceTime(30000);
3717 
3718     VerifyOrQuit(sRaValidated);
3719     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
3720 
3721     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3722     // Check Network Data to now use default route due to the
3723     // on-link prefix from router A.
3724 
3725     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
3726 
3727     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3728     // Wait for more than 1800 seconds to let the deprecating
3729     // prefixes expire (keep sending RA from router A).
3730 
3731     for (uint16_t index = 0; index < 185; index++)
3732     {
3733         SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3734         AdvanceTime(10 * 1000);
3735     }
3736 
3737     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
3738 
3739     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3740     // Disable the instance and re-enable it and restart Routing Manager.
3741 
3742     Log("Disabling and re-enabling OT Instance again");
3743 
3744     testFreeInstance(sInstance);
3745     InitTest(/* aEnablBorderRouting */ false, /* aAfterReset */ true);
3746 
3747     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3748     AdvanceTime(100);
3749 
3750     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3751     // Send RA from router A advertising an on-link prefix.
3752 
3753     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3754 
3755     sRaValidated = false;
3756     sExpectedPio = kNoPio;
3757 
3758     AdvanceTime(30000);
3759 
3760     VerifyOrQuit(sRaValidated);
3761     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 0);
3762 
3763     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3764     // Check Network Data still contains the default route.
3765 
3766     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
3767 
3768     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3769 
3770     Log("End of TestSavedOnLinkPrefixes");
3771     FinalizeTest();
3772 }
3773 #endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
3774 
3775 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
TestAutoEnableOfSrpServer(void)3776 void TestAutoEnableOfSrpServer(void)
3777 {
3778     Ip6::Prefix  localOnLink;
3779     Ip6::Prefix  localOmr;
3780     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
3781     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
3782     uint16_t     heapAllocations;
3783 
3784     Log("--------------------------------------------------------------------------------------------");
3785     Log("TestAutoEnableOfSrpServer");
3786 
3787     InitTest();
3788 
3789     heapAllocations = sHeapAllocatedPtrs.GetLength();
3790 
3791     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3792     // Check SRP Server state and enable auto-enable mode
3793 
3794     otSrpServerSetAutoEnableMode(sInstance, true);
3795     VerifyOrQuit(otSrpServerIsAutoEnableMode(sInstance));
3796     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3797 
3798     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3799     // Start Routing Manager. Check emitted RS and RA messages.
3800 
3801     sRsEmitted   = false;
3802     sRaValidated = false;
3803     sExpectedPio = kPioAdvertisingLocalOnLink;
3804     sExpectedRios.Clear();
3805 
3806     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3807 
3808     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3809     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3810 
3811     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3812     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3813 
3814     sExpectedRios.Add(localOmr);
3815 
3816     AdvanceTime(30000);
3817 
3818     VerifyOrQuit(sRsEmitted);
3819     VerifyOrQuit(sRaValidated);
3820     VerifyOrQuit(sExpectedRios.SawAll());
3821     Log("Received RA was validated");
3822 
3823     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3824     // Validate that SRP server was auto-enabled
3825 
3826     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3827     Log("Srp::Server is enabled");
3828 
3829     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3830     // Signal that infra if state changed and is no longer running.
3831     // This should stop Routing Manager and in turn the SRP server.
3832 
3833     sRaValidated = false;
3834     sExpectedPio = kPioDeprecatingLocalOnLink;
3835 
3836     Log("Signal infra if is not running");
3837     SuccessOrQuit(otPlatInfraIfStateChanged(sInstance, kInfraIfIndex, false));
3838     AdvanceTime(1);
3839 
3840     VerifyOrQuit(sRaValidated);
3841 
3842     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3843     // Check that SRP server is disabled.
3844 
3845     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3846     Log("Srp::Server is disabled");
3847 
3848     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3849     // Signal that infra if state changed and is running again.
3850 
3851     sRsEmitted   = false;
3852     sRaValidated = false;
3853     sExpectedPio = kPioAdvertisingLocalOnLink;
3854     sExpectedRios.Add(localOmr);
3855 
3856     Log("Signal infra if is running");
3857     SuccessOrQuit(otPlatInfraIfStateChanged(sInstance, kInfraIfIndex, true));
3858 
3859     AdvanceTime(30000);
3860 
3861     VerifyOrQuit(sRsEmitted);
3862     VerifyOrQuit(sRaValidated);
3863     VerifyOrQuit(sExpectedRios.SawAll());
3864     Log("Received RA was validated");
3865 
3866     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3867     // Check that SRP server is enabled again.
3868 
3869     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3870     Log("Srp::Server is enabled");
3871 
3872     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3873     // Disable `RoutingManager` explicitly.
3874 
3875     sRaValidated = false;
3876     sExpectedPio = kPioDeprecatingLocalOnLink;
3877 
3878     Log("Disabling RoutingManager");
3879     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
3880     AdvanceTime(1);
3881 
3882     VerifyOrQuit(sRaValidated);
3883 
3884     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3885     // Check that SRP server is also disabled.
3886 
3887     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3888     Log("Srp::Server is disabled");
3889 
3890     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3891     // Disable auto-enable mode on SRP server.
3892 
3893     otSrpServerSetAutoEnableMode(sInstance, false);
3894     VerifyOrQuit(!otSrpServerIsAutoEnableMode(sInstance));
3895     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3896 
3897     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3898     // Re-start Routing Manager. Check emitted RS and RA messages.
3899     // This cycle, router A will send a RA including a PIO.
3900 
3901     sRsEmitted   = false;
3902     sRaValidated = false;
3903     sExpectedPio = kNoPio;
3904     sExpectedRios.Clear();
3905 
3906     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3907 
3908     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3909     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3910 
3911     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3912     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3913 
3914     sExpectedRios.Add(localOmr);
3915 
3916     AdvanceTime(2000);
3917 
3918     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3919 
3920     AdvanceTime(30000);
3921 
3922     VerifyOrQuit(sRsEmitted);
3923     VerifyOrQuit(sRaValidated);
3924     VerifyOrQuit(sExpectedRios.SawAll());
3925     Log("Received RA was validated");
3926 
3927     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3928     // Check that SRP server is still disabled.
3929 
3930     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3931     Log("Srp::Server is disabled");
3932 
3933     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3934     // Enable auto-enable mode on SRP server. Since `RoutingManager`
3935     // is already done with initial policy evaluation, the SRP server
3936     // must be started immediately.
3937 
3938     otSrpServerSetAutoEnableMode(sInstance, true);
3939     VerifyOrQuit(otSrpServerIsAutoEnableMode(sInstance));
3940 
3941     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3942     Log("Srp::Server is enabled");
3943 
3944     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3945     // Disable auto-enable mode on SRP server. It must not impact
3946     // its current state and it should remain enabled.
3947 
3948     otSrpServerSetAutoEnableMode(sInstance, false);
3949     VerifyOrQuit(!otSrpServerIsAutoEnableMode(sInstance));
3950 
3951     AdvanceTime(2000);
3952     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3953     Log("Srp::Server is enabled");
3954 
3955     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3956     // Signal that infra if state changed and is no longer running.
3957     // This should stop Routing Manager.
3958 
3959     sRaValidated = false;
3960 
3961     Log("Signal infra if is not running");
3962     SuccessOrQuit(otPlatInfraIfStateChanged(sInstance, kInfraIfIndex, false));
3963     AdvanceTime(1);
3964 
3965     VerifyOrQuit(sRaValidated);
3966 
3967     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3968     // Re-enable auto-enable mode on SRP server. Since `RoutingManager`
3969     // is stopped (infra if is down), the SRP serer must be stopped
3970     // immediately.
3971 
3972     otSrpServerSetAutoEnableMode(sInstance, true);
3973     VerifyOrQuit(otSrpServerIsAutoEnableMode(sInstance));
3974 
3975     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3976     Log("Srp::Server is disabled");
3977 
3978     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3979 
3980     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() == heapAllocations);
3981 
3982     Log("End of TestAutoEnableOfSrpServer");
3983     FinalizeTest();
3984 }
3985 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
3986 
3987 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
TestNat64PrefixSelection(void)3988 void TestNat64PrefixSelection(void)
3989 {
3990     Ip6::Prefix                     localNat64;
3991     Ip6::Prefix                     ailNat64 = PrefixFromString("2000:0:0:1:0:0::", 96);
3992     Ip6::Prefix                     localOmr;
3993     Ip6::Prefix                     omrPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
3994     NetworkData::OnMeshPrefixConfig prefixConfig;
3995     uint16_t                        heapAllocations;
3996 
3997     Log("--------------------------------------------------------------------------------------------");
3998     Log("TestNat64PrefixSelection");
3999 
4000     InitTest();
4001 
4002     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4003     // Start Routing Manager. Check local NAT64 prefix generation.
4004 
4005     heapAllocations = sHeapAllocatedPtrs.GetLength();
4006     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
4007     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetNat64Prefix(localNat64));
4008     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
4009 
4010     Log("Local nat64 prefix is %s", localNat64.ToString().AsCString());
4011     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
4012 
4013     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4014     // Enable Nat64 Prefix Manager. Check local NAT64 prefix in Network Data.
4015 
4016     sInstance->Get<BorderRouter::RoutingManager>().SetNat64PrefixManagerEnabled(true);
4017 
4018     AdvanceTime(20000);
4019 
4020     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4021     VerifyNat64PrefixInNetData(localNat64);
4022 
4023     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4024     // AIL NAT64 prefix discovered. No infra-derived OMR prefix in Network Data.
4025     // Check local NAT64 prefix in Network Data.
4026 
4027     DiscoverNat64Prefix(ailNat64);
4028 
4029     AdvanceTime(20000);
4030 
4031     VerifyNat64PrefixInNetData(localNat64);
4032 
4033     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4034     // Add a medium preference OMR prefix into Network Data.
4035     // Check AIL NAT64 prefix published in Network Data.
4036 
4037     prefixConfig.Clear();
4038     prefixConfig.mPrefix       = omrPrefix;
4039     prefixConfig.mStable       = true;
4040     prefixConfig.mSlaac        = true;
4041     prefixConfig.mPreferred    = true;
4042     prefixConfig.mOnMesh       = true;
4043     prefixConfig.mDefaultRoute = false;
4044     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
4045 
4046     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
4047     SuccessOrQuit(otBorderRouterRegister(sInstance));
4048 
4049     AdvanceTime(20000);
4050 
4051     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ false);
4052     VerifyNat64PrefixInNetData(ailNat64);
4053 
4054     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4055     // AIL NAT64 prefix removed.
4056     // Check local NAT64 prefix in Network Data.
4057 
4058     ailNat64.Clear();
4059     DiscoverNat64Prefix(ailNat64);
4060 
4061     AdvanceTime(20000);
4062 
4063     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ false);
4064     VerifyNat64PrefixInNetData(localNat64);
4065 
4066     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
4067     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() == heapAllocations);
4068 
4069     Log("End of TestNat64PrefixSelection");
4070     FinalizeTest();
4071 }
4072 #endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
4073 
4074 #if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
VerifyPdOmrPrefix(const Ip6::Prefix & aPrefix)4075 void VerifyPdOmrPrefix(const Ip6::Prefix &aPrefix)
4076 {
4077     otBorderRoutingPrefixTableEntry platformPrefixInfo;
4078 
4079     VerifyOrQuit(otBorderRoutingGetPdOmrPrefix(sInstance, &platformPrefixInfo) == OT_ERROR_NONE);
4080     VerifyOrQuit(AsCoreType(&platformPrefixInfo.mPrefix) == aPrefix);
4081 }
4082 
VerifyNoPdOmrPrefix()4083 void VerifyNoPdOmrPrefix()
4084 {
4085     otBorderRoutingPrefixTableEntry platformPrefixInfo;
4086 
4087     VerifyOrQuit(otBorderRoutingGetPdOmrPrefix(sInstance, &platformPrefixInfo) == OT_ERROR_NOT_FOUND);
4088 }
4089 
TestBorderRoutingProcessPlatfromGeneratedNd(void)4090 void TestBorderRoutingProcessPlatfromGeneratedNd(void)
4091 {
4092     Ip6::Prefix localOmr;
4093     uint16_t    heapAllocations;
4094 
4095     Log("--------------------------------------------------------------------------------------------");
4096     Log("TestBorderRoutingProcessPlatfromGeneratedNd");
4097 
4098     InitTest(/* aEnableBorderRouting */ true);
4099     heapAllocations = sHeapAllocatedPtrs.GetLength();
4100 
4101     otBorderRoutingDhcp6PdSetEnabled(sInstance, true);
4102 
4103     {
4104         SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
4105     }
4106 
4107     // 0. Reject invalid RA.
4108     Log("0. Invalid RA message.");
4109     {
4110         {
4111             const uint8_t testInvalidRaMessage[] = {
4112                 0x86, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4113             };
4114 
4115             otPlatBorderRoutingProcessIcmp6Ra(sInstance, testInvalidRaMessage, sizeof(testInvalidRaMessage));
4116             VerifyNoPdOmrPrefix();
4117         }
4118 
4119         {
4120             const uint8_t testInvalidRaMessage[] = {
4121                 0x87, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4122             };
4123 
4124             otPlatBorderRoutingProcessIcmp6Ra(sInstance, testInvalidRaMessage, sizeof(testInvalidRaMessage));
4125             VerifyNoPdOmrPrefix();
4126         }
4127 
4128         {
4129             const uint8_t testRaMessageWithInvalidPrefix[] = {
4130                 0x86, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4131                 0x03, 0x04, 0x41, 0xc0, 0x00, 0x00, 0x10, 0xe1, 0x00, 0x00, 0x04, 0xd2, 0x00, 0x00, 0x00, 0x00,
4132                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4133             };
4134 
4135             otPlatBorderRoutingProcessIcmp6Ra(sInstance, testRaMessageWithInvalidPrefix,
4136                                               sizeof(testRaMessageWithInvalidPrefix));
4137             VerifyNoPdOmrPrefix();
4138         }
4139     }
4140 
4141     // 1. Publish a prefix, and wait until it expired.
4142     Log("1. Simple RA message.");
4143     {
4144         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:dead:beef::", 64);
4145 
4146         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
4147 
4148         sExpectedRios.Add(raPrefix);
4149         AdvanceTime(10000);
4150 
4151         VerifyPdOmrPrefix(raPrefix);
4152         VerifyOrQuit(sExpectedRios.SawAll());
4153         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4154 
4155         AdvanceTime(1500000);
4156         sExpectedRios.Clear();
4157         VerifyPdOmrPrefix(raPrefix);
4158         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4159 
4160         AdvanceTime(400000);
4161         // Deprecated prefixes will be removed.
4162         VerifyNoPdOmrPrefix();
4163         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4164     }
4165 
4166     // 1.1. Publish a prefix, and wait until it expired.
4167     //      Multiple prefixes are advertised, only the smallest one will be used.
4168     Log("1.1. RA message with multiple prefixes.");
4169     {
4170         Ip6::Prefix raPrefix    = PrefixFromString("2001:db8:dead:beef::", 64);
4171         Ip6::Prefix ulaRaPrefix = PrefixFromString("fd01:db8:deaf:beef::", 64);
4172 
4173         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(ulaRaPrefix, kValidLitime * 2, kPreferredLifetime * 2),
4174                                                        Pio(raPrefix, kValidLitime, kPreferredLifetime)});
4175 
4176         sExpectedRios.Add(raPrefix);
4177         AdvanceTime(10000);
4178 
4179         VerifyPdOmrPrefix(raPrefix);
4180         VerifyOrQuit(sExpectedRios.SawAll());
4181         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4182 
4183         AdvanceTime(1500000);
4184         sExpectedRios.Clear();
4185         VerifyPdOmrPrefix(raPrefix);
4186         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4187 
4188         AdvanceTime(400000);
4189         // Deprecated prefixes will be removed.
4190         VerifyNoPdOmrPrefix();
4191         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4192     }
4193 
4194     // 2. Publish a prefix, and renew it before it expired.
4195     Log("2. Renew prefix lifetime.");
4196     {
4197         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:1:2::", 64);
4198 
4199         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
4200 
4201         sExpectedRios.Add(raPrefix);
4202         AdvanceTime(10000);
4203 
4204         VerifyPdOmrPrefix(raPrefix);
4205         VerifyOrQuit(sExpectedRios.SawAll());
4206         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4207 
4208         AdvanceTime(1500000);
4209         sExpectedRios.Clear();
4210         VerifyPdOmrPrefix(raPrefix);
4211         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4212 
4213         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
4214 
4215         AdvanceTime(400000);
4216         VerifyPdOmrPrefix(raPrefix);
4217         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4218 
4219         AdvanceTime(1500000);
4220         VerifyNoPdOmrPrefix();
4221         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4222     }
4223 
4224     // 3. Publish a prefix, and publish another prefix to replace it (with goodbye ra).
4225     Log("3. Update prefix.");
4226     {
4227         Ip6::Prefix raPrefix    = PrefixFromString("2001:db8:1:2::", 64);
4228         Ip6::Prefix newRaPrefix = PrefixFromString("2001:db8:3:4::", 64);
4229 
4230         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
4231 
4232         sExpectedRios.Add(raPrefix);
4233         sExpectedRios.Clear();
4234         AdvanceTime(10000);
4235 
4236         VerifyPdOmrPrefix(raPrefix);
4237         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4238 
4239         AdvanceTime(1000000);
4240         VerifyPdOmrPrefix(raPrefix);
4241 
4242         SendRouterAdvertToBorderRoutingProcessIcmp6Ra(
4243             {Pio(raPrefix, 0, 0), Pio(newRaPrefix, kValidLitime, kPreferredLifetime)});
4244         sExpectedRios.Add(newRaPrefix);
4245 
4246         AdvanceTime(1000000);
4247         VerifyOrQuit(sExpectedRios.SawAll());
4248         VerifyPdOmrPrefix(newRaPrefix);
4249 
4250         AdvanceTime(1000000);
4251         VerifyNoPdOmrPrefix();
4252         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4253     }
4254 
4255     // 4. Short prefix will be extended to /64.
4256     Log("4. Short prefix");
4257     {
4258         // The prefix will be padded to a /64 prefix.
4259         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:cafe:0::", 64);
4260         Ip6::Prefix realRaPrefix;
4261 
4262         realRaPrefix.Set(raPrefix.GetBytes(), 48);
4263         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(realRaPrefix, kValidLitime, kPreferredLifetime)});
4264 
4265         sExpectedRios.Add(raPrefix);
4266         AdvanceTime(10000);
4267 
4268         VerifyPdOmrPrefix(raPrefix);
4269         VerifyOrQuit(sExpectedRios.SawAll());
4270         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4271 
4272         AdvanceTime(1500000);
4273         sExpectedRios.Clear();
4274         VerifyPdOmrPrefix(raPrefix);
4275         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4276 
4277         AdvanceTime(400000);
4278         // Deprecated prefixes will be removed.
4279         VerifyNoPdOmrPrefix();
4280         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4281     }
4282 
4283     // 5. Publish a prefix with long lifetime, and wait until it expired.
4284     Log("5. RA message with long prefix lifetime");
4285     {
4286         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:dead:beef::", 64);
4287 
4288         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, 5000, 5000)});
4289 
4290         sExpectedRios.Add(raPrefix);
4291         AdvanceTime(10 * 1000);
4292 
4293         VerifyPdOmrPrefix(raPrefix);
4294         VerifyOrQuit(sExpectedRios.SawAll());
4295         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4296 
4297         AdvanceTime(4900 * 1000);
4298         sExpectedRios.Clear();
4299         VerifyPdOmrPrefix(raPrefix);
4300         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
4301 
4302         AdvanceTime(200 * 1000);
4303         // Deprecated prefixes will be removed.
4304         VerifyNoPdOmrPrefix();
4305         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
4306     }
4307 
4308     SuccessOrQuit(otBorderRoutingSetEnabled(sInstance, false));
4309     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
4310 
4311     Log("End of TestBorderRoutingProcessPlatfromGeneratedNd");
4312 
4313     FinalizeTest();
4314 }
4315 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
4316 
4317 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
4318 
4319 } // namespace ot
4320 
main(void)4321 int main(void)
4322 {
4323 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
4324     ot::TestSamePrefixesFromMultipleRouters();
4325     ot::TestOmrSelection();
4326     ot::TestDefaultRoute();
4327     ot::TestAdvNonUlaRoute();
4328     ot::TestFavoredOnLinkPrefix();
4329     ot::TestLocalOnLinkPrefixDeprecation();
4330 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
4331     ot::TestDomainPrefixAsOmr();
4332 #endif
4333     ot::TestExtPanIdChange();
4334     ot::TestConflictingPrefix();
4335     ot::TestPrefixStaleTime();
4336     ot::TestRouterNsProbe();
4337     ot::TestLearningAndCopyingOfFlags();
4338     ot::TestLearnRaHeader();
4339 #if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
4340     ot::TestSavedOnLinkPrefixes();
4341 #endif
4342 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
4343     ot::TestAutoEnableOfSrpServer();
4344 #endif
4345 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
4346     ot::TestNat64PrefixSelection();
4347 #endif
4348 #if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
4349     ot::TestBorderRoutingProcessPlatfromGeneratedNd();
4350 #endif
4351 
4352     printf("All tests passed\n");
4353 #else
4354     printf("BORDER_ROUTING feature is not enabled\n");
4355 #endif
4356 
4357     return 0;
4358 }
4359