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/instance.hpp"
42 #include "common/time.hpp"
43 #include "net/icmp6.hpp"
44 #include "net/nd6.hpp"
45 
46 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
47 
48 using namespace ot;
49 
50 // Logs a message and adds current time (sNow) as "<hours>:<min>:<secs>.<msec>"
51 #define Log(...)                                                                                         \
52     printf("%02u:%02u:%02u.%03u " OT_FIRST_ARG(__VA_ARGS__) "\n", (sNow / 3600000), (sNow / 60000) % 60, \
53            (sNow / 1000) % 60, sNow % 1000 OT_REST_ARGS(__VA_ARGS__))
54 
55 static constexpr uint32_t kInfraIfIndex     = 1;
56 static const char         kInfraIfAddress[] = "fe80::1";
57 
58 static constexpr uint32_t kValidLitime       = 2000;
59 static constexpr uint32_t kPreferredLifetime = 1800;
60 
61 static constexpr uint16_t kMaxRaSize              = 800;
62 static constexpr uint16_t kMaxDeprecatingPrefixes = 16;
63 
64 static constexpr otOperationalDataset kDataset = {
65     .mActiveTimestamp =
66         {
67             .mSeconds       = 1,
68             .mTicks         = 0,
69             .mAuthoritative = false,
70         },
71     .mNetworkKey =
72         {
73             .m8 = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
74         },
75     .mNetworkName = {"OpenThread"},
76     .mExtendedPanId =
77         {
78             .m8 = {0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0xca, 0xfe},
79         },
80     .mMeshLocalPrefix =
81         {
82             .m8 = {0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
83         },
84     .mPanId   = 0x1234,
85     .mChannel = 11,
86     .mPskc =
87         {
88             .m8 = {0xc2, 0x3a, 0x76, 0xe9, 0x8f, 0x1a, 0x64, 0x83, 0x63, 0x9b, 0x1a, 0xc1, 0x27, 0x1e, 0x2e, 0x27},
89         },
90     .mSecurityPolicy =
91         {
92             .mRotationTime                 = 672,
93             .mObtainNetworkKeyEnabled      = true,
94             .mNativeCommissioningEnabled   = true,
95             .mRoutersEnabled               = true,
96             .mExternalCommissioningEnabled = true,
97         },
98     .mChannelMask = 0x07fff800,
99     .mComponents =
100         {
101             .mIsActiveTimestampPresent = true,
102             .mIsNetworkKeyPresent      = true,
103             .mIsNetworkNamePresent     = true,
104             .mIsExtendedPanIdPresent   = true,
105             .mIsMeshLocalPrefixPresent = true,
106             .mIsPanIdPresent           = true,
107             .mIsChannelPresent         = true,
108             .mIsPskcPresent            = true,
109             .mIsSecurityPolicyPresent  = true,
110             .mIsChannelMaskPresent     = true,
111         },
112 };
113 
114 static ot::Instance *sInstance;
115 
116 static uint32_t sNow = 0;
117 static uint32_t sAlarmTime;
118 static bool     sAlarmOn = false;
119 
120 static otRadioFrame sRadioTxFrame;
121 static uint8_t      sRadioTxFramePsdu[OT_RADIO_FRAME_MAX_SIZE];
122 static bool         sRadioTxOngoing = false;
123 
124 using Icmp6Packet = Ip6::Nd::RouterAdvertMessage::Icmp6Packet;
125 
126 enum ExpectedPio
127 {
128     kNoPio,                     // Expect to see no PIO in RA.
129     kPioAdvertisingLocalOnLink, // Expect to see local on-link prefix advertised (non-zero preferred lifetime).
130     kPioDeprecatingLocalOnLink, // Expect to see local on-link prefix deprecated (zero preferred lifetime).
131 };
132 
133 struct DeprecatingPrefix
134 {
135     DeprecatingPrefix(void) = default;
136 
DeprecatingPrefixDeprecatingPrefix137     DeprecatingPrefix(const Ip6::Prefix &aPrefix, uint32_t aLifetime)
138         : mPrefix(aPrefix)
139         , mLifetime(aLifetime)
140     {
141     }
142 
MatchesDeprecatingPrefix143     bool Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
144 
145     Ip6::Prefix mPrefix;   // Old on-link prefix being deprecated.
146     uint32_t    mLifetime; // Valid lifetime of prefix from PIO.
147 };
148 
149 static Ip6::Address sInfraIfAddress;
150 
151 bool        sRsEmitted;      // Indicates if an RS message was emitted by BR.
152 bool        sRaValidated;    // Indicates if an RA was emitted by BR and successfully validated.
153 bool        sNsEmitted;      // Indicates if an NS message was emitted by BR.
154 bool        sRespondToNs;    // Indicates whether or not to respond to NS.
155 ExpectedPio sExpectedPio;    // Expected PIO in the emitted RA by BR (MUST be seen in RA to set `sRaValidated`).
156 uint32_t    sOnLinkLifetime; // Valid lifetime for local on-link prefix from the last processed RA.
157 
158 // Array containing deprecating prefixes from PIOs in the last processed RA.
159 Array<DeprecatingPrefix, kMaxDeprecatingPrefixes> sDeprecatingPrefixes;
160 
161 static constexpr uint16_t kMaxRioPrefixes = 10;
162 
163 struct RioPrefix
164 {
165     RioPrefix(void) = default;
166 
RioPrefixRioPrefix167     explicit RioPrefix(const Ip6::Prefix &aPrefix)
168         : mSawInRa(false)
169         , mPrefix(aPrefix)
170         , mLifetime(0)
171     {
172     }
173 
174     bool        mSawInRa;  // Indicate whether or not this prefix was seen in the emitted RA (as RIO).
175     Ip6::Prefix mPrefix;   // The RIO prefix.
176     uint32_t    mLifetime; // The RIO prefix lifetime - only valid when `mSawInRa`
177 };
178 
179 class ExpectedRios : public Array<RioPrefix, kMaxRioPrefixes>
180 {
181 public:
Add(const Ip6::Prefix & aPrefix)182     void Add(const Ip6::Prefix &aPrefix) { SuccessOrQuit(PushBack(RioPrefix(aPrefix))); }
183 
SawAll(void) const184     bool SawAll(void) const
185     {
186         bool sawAll = true;
187 
188         for (const RioPrefix &rioPrefix : *this)
189         {
190             if (!rioPrefix.mSawInRa)
191             {
192                 sawAll = false;
193                 break;
194             }
195         }
196 
197         return sawAll;
198     }
199 };
200 
201 ExpectedRios sExpectedRios; // Expected RIO prefixes in emitted RAs.
202 
203 //----------------------------------------------------------------------------------------------------------------------
204 // Function prototypes
205 
206 void        ProcessRadioTxAndTasklets(void);
207 void        AdvanceTime(uint32_t aDuration);
208 void        LogRouterAdvert(const Icmp6Packet &aPacket);
209 void        ValidateRouterAdvert(const Icmp6Packet &aPacket);
210 const char *PreferenceToString(int8_t aPreference);
211 void        SendRouterAdvert(const Ip6::Address &aAddress, const Icmp6Packet &aPacket);
212 void        SendNeighborAdvert(const Ip6::Address &aAddress, const Ip6::Nd::NeighborAdvertMessage &aNaMessage);
213 void        DiscoverNat64Prefix(const Ip6::Prefix &aPrefix);
214 
215 #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)216 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
217 {
218     OT_UNUSED_VARIABLE(aLogLevel);
219     OT_UNUSED_VARIABLE(aLogRegion);
220 
221     va_list args;
222 
223     printf("   ");
224     va_start(args, aFormat);
225     vprintf(aFormat, args);
226     va_end(args);
227     printf("\n");
228 }
229 #endif
230 
231 //----------------------------------------------------------------------------------------------------------------------
232 // `otPlatRadio
233 
234 extern "C" {
235 
otPlatRadioGetCaps(otInstance *)236 otRadioCaps otPlatRadioGetCaps(otInstance *) { return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF; }
237 
otPlatRadioTransmit(otInstance *,otRadioFrame *)238 otError otPlatRadioTransmit(otInstance *, otRadioFrame *)
239 {
240     sRadioTxOngoing = true;
241 
242     return OT_ERROR_NONE;
243 }
244 
otPlatRadioGetTransmitBuffer(otInstance *)245 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *) { return &sRadioTxFrame; }
246 
247 //----------------------------------------------------------------------------------------------------------------------
248 // `otPlatAlaram
249 
otPlatAlarmMilliStop(otInstance *)250 void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
251 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)252 void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
253 {
254     sAlarmOn   = true;
255     sAlarmTime = aT0 + aDt;
256 }
257 
otPlatAlarmMilliGetNow(void)258 uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
259 
260 //---------------------------------------------------------------------------------------------------------------------
261 // otPlatInfraIf
262 
otPlatInfraIfHasAddress(uint32_t aInfraIfIndex,const otIp6Address * aAddress)263 bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress)
264 {
265     VerifyOrQuit(aInfraIfIndex == kInfraIfIndex);
266 
267     return AsCoreType(aAddress) == sInfraIfAddress;
268 }
269 
otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,const otIp6Address * aDestAddress,const uint8_t * aBuffer,uint16_t aBufferLength)270 otError otPlatInfraIfSendIcmp6Nd(uint32_t            aInfraIfIndex,
271                                  const otIp6Address *aDestAddress,
272                                  const uint8_t      *aBuffer,
273                                  uint16_t            aBufferLength)
274 {
275     Icmp6Packet packet;
276 
277     Log("otPlatInfraIfSendIcmp6Nd(aDestAddr: %s, aBufferLength:%u)", AsCoreType(aDestAddress).ToString().AsCString(),
278         aBufferLength);
279 
280     VerifyOrQuit(aInfraIfIndex == kInfraIfIndex);
281 
282     packet.Init(aBuffer, aBufferLength);
283 
284     VerifyOrQuit(aBufferLength >= sizeof(Ip6::Icmp::Header));
285 
286     switch (reinterpret_cast<const Ip6::Icmp::Header *>(aBuffer)->GetType())
287     {
288     case Ip6::Icmp::Header::kTypeRouterSolicit:
289         Log("  Router Solicit message");
290         sRsEmitted = true;
291         break;
292 
293     case Ip6::Icmp::Header::kTypeRouterAdvert:
294         Log("  Router Advertisement message");
295         LogRouterAdvert(packet);
296         ValidateRouterAdvert(packet);
297         break;
298 
299     case Ip6::Icmp::Header::kTypeNeighborSolicit:
300     {
301         const Ip6::Nd::NeighborSolicitMessage *nsMsg =
302             reinterpret_cast<const Ip6::Nd::NeighborSolicitMessage *>(packet.GetBytes());
303 
304         Log("  Neighbor Solicit message");
305 
306         VerifyOrQuit(packet.GetLength() >= sizeof(Ip6::Nd::NeighborSolicitMessage));
307         VerifyOrQuit(nsMsg->IsValid());
308         sNsEmitted = true;
309 
310         if (sRespondToNs)
311         {
312             Ip6::Nd::NeighborAdvertMessage naMsg;
313 
314             naMsg.SetTargetAddress(nsMsg->GetTargetAddress());
315             naMsg.SetRouterFlag();
316             naMsg.SetSolicitedFlag();
317             SendNeighborAdvert(AsCoreType(aDestAddress), naMsg);
318         }
319 
320         break;
321     }
322 
323     default:
324         VerifyOrQuit(false, "Bad ICMP6 type");
325     }
326 
327     return OT_ERROR_NONE;
328 }
329 
330 } // extern "C"
331 
332 //---------------------------------------------------------------------------------------------------------------------
333 
ProcessRadioTxAndTasklets(void)334 void ProcessRadioTxAndTasklets(void)
335 {
336     do
337     {
338         if (sRadioTxOngoing)
339         {
340             sRadioTxOngoing = false;
341             otPlatRadioTxStarted(sInstance, &sRadioTxFrame);
342             otPlatRadioTxDone(sInstance, &sRadioTxFrame, nullptr, OT_ERROR_NONE);
343         }
344 
345         otTaskletsProcess(sInstance);
346     } while (otTaskletsArePending(sInstance));
347 }
348 
AdvanceTime(uint32_t aDuration)349 void AdvanceTime(uint32_t aDuration)
350 {
351     uint32_t time = sNow + aDuration;
352 
353     Log("AdvanceTime for %u.%03u", aDuration / 1000, aDuration % 1000);
354 
355     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
356     {
357         ProcessRadioTxAndTasklets();
358         sNow = sAlarmTime;
359         otPlatAlarmMilliFired(sInstance);
360     }
361 
362     ProcessRadioTxAndTasklets();
363     sNow = time;
364 }
365 
ValidateRouterAdvert(const Icmp6Packet & aPacket)366 void ValidateRouterAdvert(const Icmp6Packet &aPacket)
367 {
368     constexpr uint8_t kMaxPrefixes = 16;
369 
370     Ip6::Nd::RouterAdvertMessage     raMsg(aPacket);
371     bool                             sawExpectedPio = false;
372     Array<Ip6::Prefix, kMaxPrefixes> pioPrefixes;
373     Array<Ip6::Prefix, kMaxPrefixes> rioPrefixes;
374 
375     VerifyOrQuit(raMsg.IsValid());
376 
377     sDeprecatingPrefixes.Clear();
378 
379     for (const Ip6::Nd::Option &option : raMsg)
380     {
381         switch (option.GetType())
382         {
383         case Ip6::Nd::Option::kTypePrefixInfo:
384         {
385             const Ip6::Nd::PrefixInfoOption &pio = static_cast<const Ip6::Nd::PrefixInfoOption &>(option);
386             Ip6::Prefix                      prefix;
387             Ip6::Prefix                      localOnLink;
388 
389             VerifyOrQuit(pio.IsValid());
390             pio.GetPrefix(prefix);
391 
392             VerifyOrQuit(!pioPrefixes.Contains(prefix), "Duplicate PIO prefix in RA");
393             SuccessOrQuit(pioPrefixes.PushBack(prefix));
394 
395             SuccessOrQuit(otBorderRoutingGetOnLinkPrefix(sInstance, &localOnLink));
396 
397             if (prefix == localOnLink)
398             {
399                 switch (sExpectedPio)
400                 {
401                 case kNoPio:
402                     break;
403 
404                 case kPioAdvertisingLocalOnLink:
405                     if (pio.GetPreferredLifetime() > 0)
406                     {
407                         sOnLinkLifetime = pio.GetValidLifetime();
408                         sawExpectedPio  = true;
409                     }
410                     break;
411 
412                 case kPioDeprecatingLocalOnLink:
413                     if (pio.GetPreferredLifetime() == 0)
414                     {
415                         sOnLinkLifetime = pio.GetValidLifetime();
416                         sawExpectedPio  = true;
417                     }
418                     break;
419                 }
420             }
421             else
422             {
423                 VerifyOrQuit(pio.GetPreferredLifetime() == 0, "Old on link prefix is not deprecated");
424                 SuccessOrQuit(sDeprecatingPrefixes.PushBack(DeprecatingPrefix(prefix, pio.GetValidLifetime())));
425             }
426             break;
427         }
428 
429         case Ip6::Nd::Option::kTypeRouteInfo:
430         {
431             const Ip6::Nd::RouteInfoOption &rio = static_cast<const Ip6::Nd::RouteInfoOption &>(option);
432             Ip6::Prefix                     prefix;
433 
434             VerifyOrQuit(rio.IsValid());
435             rio.GetPrefix(prefix);
436 
437             VerifyOrQuit(!rioPrefixes.Contains(prefix), "Duplicate RIO prefix in RA");
438             SuccessOrQuit(rioPrefixes.PushBack(prefix));
439 
440             for (RioPrefix &rioPrefix : sExpectedRios)
441             {
442                 if (prefix == rioPrefix.mPrefix)
443                 {
444                     rioPrefix.mSawInRa  = true;
445                     rioPrefix.mLifetime = rio.GetRouteLifetime();
446                 }
447             }
448 
449             break;
450         }
451 
452         default:
453             VerifyOrQuit(false, "Unexpected option type in RA msg");
454         }
455     }
456 
457     if (!sRaValidated)
458     {
459         switch (sExpectedPio)
460         {
461         case kNoPio:
462             break;
463         case kPioAdvertisingLocalOnLink:
464         case kPioDeprecatingLocalOnLink:
465             // First emitted RAs may not yet have the expected PIO
466             // so we exit and not set `sRaValidated` to allow it
467             // to be checked for next received RA.
468             VerifyOrExit(sawExpectedPio);
469             break;
470         }
471 
472         sRaValidated = true;
473     }
474 
475 exit:
476     return;
477 }
478 
LogRouterAdvert(const Icmp6Packet & aPacket)479 void LogRouterAdvert(const Icmp6Packet &aPacket)
480 {
481     Ip6::Nd::RouterAdvertMessage raMsg(aPacket);
482 
483     VerifyOrQuit(raMsg.IsValid());
484 
485     Log("     RA header - lifetime %u, prf:%s", raMsg.GetHeader().GetRouterLifetime(),
486         PreferenceToString(raMsg.GetHeader().GetDefaultRouterPreference()));
487 
488     for (const Ip6::Nd::Option &option : raMsg)
489     {
490         switch (option.GetType())
491         {
492         case Ip6::Nd::Option::kTypePrefixInfo:
493         {
494             const Ip6::Nd::PrefixInfoOption &pio = static_cast<const Ip6::Nd::PrefixInfoOption &>(option);
495             Ip6::Prefix                      prefix;
496 
497             VerifyOrQuit(pio.IsValid());
498             pio.GetPrefix(prefix);
499             Log("     PIO - %s, flags:%s%s, valid:%u, preferred:%u", prefix.ToString().AsCString(),
500                 pio.IsOnLinkFlagSet() ? "L" : "", pio.IsAutoAddrConfigFlagSet() ? "A" : "", pio.GetValidLifetime(),
501                 pio.GetPreferredLifetime());
502             break;
503         }
504 
505         case Ip6::Nd::Option::kTypeRouteInfo:
506         {
507             const Ip6::Nd::RouteInfoOption &rio = static_cast<const Ip6::Nd::RouteInfoOption &>(option);
508             Ip6::Prefix                     prefix;
509 
510             VerifyOrQuit(rio.IsValid());
511             rio.GetPrefix(prefix);
512             Log("     RIO - %s, prf:%s, lifetime:%u", prefix.ToString().AsCString(),
513                 PreferenceToString(rio.GetPreference()), rio.GetRouteLifetime());
514             break;
515         }
516 
517         default:
518             VerifyOrQuit(false, "Bad option type in RA msg");
519         }
520     }
521 }
522 
LogRouterAdvert(const uint8_t * aBuffer,size_t aLength)523 void LogRouterAdvert(const uint8_t *aBuffer, size_t aLength)
524 {
525     Icmp6Packet packet;
526     packet.Init(aBuffer, aLength);
527     LogRouterAdvert(packet);
528 }
529 
PreferenceToString(int8_t aPreference)530 const char *PreferenceToString(int8_t aPreference)
531 {
532     const char *str = "";
533 
534     switch (aPreference)
535     {
536     case NetworkData::kRoutePreferenceLow:
537         str = "low";
538         break;
539 
540     case NetworkData::kRoutePreferenceMedium:
541         str = "med";
542         break;
543 
544     case NetworkData::kRoutePreferenceHigh:
545         str = "high";
546         break;
547 
548     default:
549         break;
550     }
551 
552     return str;
553 }
554 
SendRouterAdvert(const Ip6::Address & aAddress,const uint8_t * aBuffer,uint16_t aLength)555 void SendRouterAdvert(const Ip6::Address &aAddress, const uint8_t *aBuffer, uint16_t aLength)
556 {
557     otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &aAddress, aBuffer, aLength);
558 }
559 
SendRouterAdvert(const Ip6::Address & aAddress,const Icmp6Packet & aPacket)560 void SendRouterAdvert(const Ip6::Address &aAddress, const Icmp6Packet &aPacket)
561 {
562     SendRouterAdvert(aAddress, aPacket.GetBytes(), aPacket.GetLength());
563 }
564 
SendNeighborAdvert(const Ip6::Address & aAddress,const Ip6::Nd::NeighborAdvertMessage & aNaMessage)565 void SendNeighborAdvert(const Ip6::Address &aAddress, const Ip6::Nd::NeighborAdvertMessage &aNaMessage)
566 {
567     Log("Sending NA from %s", aAddress.ToString().AsCString());
568     otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &aAddress, reinterpret_cast<const uint8_t *>(&aNaMessage),
569                              sizeof(aNaMessage));
570 }
571 
DiscoverNat64Prefix(const Ip6::Prefix & aPrefix)572 void DiscoverNat64Prefix(const Ip6::Prefix &aPrefix)
573 {
574     Log("Discovered NAT64 prefix %s", aPrefix.ToString().AsCString());
575 
576     otPlatInfraIfDiscoverNat64PrefixDone(sInstance, kInfraIfIndex, &aPrefix);
577 }
578 
PrefixFromString(const char * aString,uint8_t aPrefixLength)579 Ip6::Prefix PrefixFromString(const char *aString, uint8_t aPrefixLength)
580 {
581     Ip6::Prefix prefix;
582 
583     SuccessOrQuit(AsCoreType(&prefix.mPrefix).FromString(aString));
584     prefix.mLength = aPrefixLength;
585 
586     return prefix;
587 }
588 
AddressFromString(const char * aString)589 Ip6::Address AddressFromString(const char *aString)
590 {
591     Ip6::Address address;
592 
593     SuccessOrQuit(address.FromString(aString));
594 
595     return address;
596 }
597 
VerifyOmrPrefixInNetData(const Ip6::Prefix & aOmrPrefix,bool aDefaultRoute)598 void VerifyOmrPrefixInNetData(const Ip6::Prefix &aOmrPrefix, bool aDefaultRoute)
599 {
600     otNetworkDataIterator           iterator = OT_NETWORK_DATA_ITERATOR_INIT;
601     NetworkData::OnMeshPrefixConfig prefixConfig;
602 
603     Log("VerifyOmrPrefixInNetData(%s, def-route:%s)", aOmrPrefix.ToString().AsCString(), aDefaultRoute ? "yes" : "no");
604 
605     SuccessOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig));
606     VerifyOrQuit(prefixConfig.GetPrefix() == aOmrPrefix);
607     VerifyOrQuit(prefixConfig.mStable == true);
608     VerifyOrQuit(prefixConfig.mSlaac == true);
609     VerifyOrQuit(prefixConfig.mPreferred == true);
610     VerifyOrQuit(prefixConfig.mOnMesh == true);
611     VerifyOrQuit(prefixConfig.mDefaultRoute == aDefaultRoute);
612 
613     VerifyOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig) == kErrorNotFound);
614 }
615 
VerifyNoOmrPrefixInNetData(void)616 void VerifyNoOmrPrefixInNetData(void)
617 {
618     otNetworkDataIterator           iterator = OT_NETWORK_DATA_ITERATOR_INIT;
619     NetworkData::OnMeshPrefixConfig prefixConfig;
620 
621     Log("VerifyNoOmrPrefixInNetData()");
622     VerifyOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig) != kErrorNone);
623 }
624 
625 using NetworkData::RoutePreference;
626 
627 enum ExternalRouteMode : uint8_t
628 {
629     kNoRoute,
630     kDefaultRoute,
631     kUlaRoute,
632 };
633 
634 enum AdvPioMode : uint8_t
635 {
636     kSkipAdvPioCheck,
637     kWithAdvPioFlagSet,
638     kWithAdvPioCleared,
639 };
640 
VerifyExternalRouteInNetData(ExternalRouteMode aExternalRouteMode,AdvPioMode aAdvPioMode=kSkipAdvPioCheck)641 void VerifyExternalRouteInNetData(ExternalRouteMode aExternalRouteMode, AdvPioMode aAdvPioMode = kSkipAdvPioCheck)
642 {
643     Error                 error;
644     otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
645     otExternalRouteConfig routeConfig;
646 
647     error = otNetDataGetNextRoute(sInstance, &iterator, &routeConfig);
648 
649     switch (aExternalRouteMode)
650     {
651     case kNoRoute:
652         Log("VerifyExternalRouteInNetData(kNoRoute)");
653         VerifyOrQuit(error != kErrorNone);
654         break;
655 
656     case kDefaultRoute:
657         Log("VerifyExternalRouteInNetData(kDefaultRoute)");
658         VerifyOrQuit(error == kErrorNone);
659         VerifyOrQuit(routeConfig.mPrefix.mLength == 0);
660         VerifyOrQuit((aAdvPioMode == kSkipAdvPioCheck) || (routeConfig.mAdvPio == (aAdvPioMode == kWithAdvPioFlagSet)));
661         VerifyOrQuit(otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) != kErrorNone);
662         break;
663 
664     case kUlaRoute:
665         Log("VerifyExternalRouteInNetData(kUlaRoute)");
666         VerifyOrQuit(error == kErrorNone);
667         VerifyOrQuit(routeConfig.mPrefix.mLength == 7);
668         VerifyOrQuit(routeConfig.mPrefix.mPrefix.mFields.m8[0] == 0xfc);
669         VerifyOrQuit((aAdvPioMode == kSkipAdvPioCheck) || (routeConfig.mAdvPio == (aAdvPioMode == kWithAdvPioFlagSet)));
670         VerifyOrQuit(otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) != kErrorNone);
671         break;
672     }
673 }
674 
VerifyNat64PrefixInNetData(const Ip6::Prefix & aNat64Prefix)675 void VerifyNat64PrefixInNetData(const Ip6::Prefix &aNat64Prefix)
676 {
677     otNetworkDataIterator            iterator = OT_NETWORK_DATA_ITERATOR_INIT;
678     NetworkData::ExternalRouteConfig routeConfig;
679     bool                             didFind = false;
680 
681     Log("VerifyNat64PrefixInNetData()");
682 
683     while (otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) == kErrorNone)
684     {
685         if (!routeConfig.mNat64 || !routeConfig.GetPrefix().IsValidNat64())
686         {
687             continue;
688         }
689 
690         Log("   nat64 prefix:%s, prf:%s", routeConfig.GetPrefix().ToString().AsCString(),
691             PreferenceToString(routeConfig.mPreference));
692 
693         VerifyOrQuit(routeConfig.GetPrefix() == aNat64Prefix);
694         didFind = true;
695     }
696 
697     VerifyOrQuit(didFind);
698 }
699 
700 struct Pio
701 {
PioPio702     Pio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime)
703         : mPrefix(aPrefix)
704         , mValidLifetime(aValidLifetime)
705         , mPreferredLifetime(aPreferredLifetime)
706     {
707     }
708 
709     const Ip6::Prefix &mPrefix;
710     uint32_t           mValidLifetime;
711     uint32_t           mPreferredLifetime;
712 };
713 
714 struct Rio
715 {
RioRio716     Rio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, RoutePreference aPreference)
717         : mPrefix(aPrefix)
718         , mValidLifetime(aValidLifetime)
719         , mPreference(aPreference)
720     {
721     }
722 
723     const Ip6::Prefix &mPrefix;
724     uint32_t           mValidLifetime;
725     RoutePreference    mPreference;
726 };
727 
728 struct DefaultRoute
729 {
DefaultRouteDefaultRoute730     DefaultRoute(uint32_t aLifetime, RoutePreference aPreference)
731         : mLifetime(aLifetime)
732         , mPreference(aPreference)
733     {
734     }
735 
736     uint32_t        mLifetime;
737     RoutePreference mPreference;
738 };
739 
740 template <size_t N>
BuildRouterAdvert(uint8_t (& aBuffer)[N],const Pio * aPios,uint16_t aNumPios,const Rio * aRios,uint16_t aNumRios,const DefaultRoute & aDefaultRoute)741 uint16_t BuildRouterAdvert(uint8_t (&aBuffer)[N],
742                            const Pio          *aPios,
743                            uint16_t            aNumPios,
744                            const Rio          *aRios,
745                            uint16_t            aNumRios,
746                            const DefaultRoute &aDefaultRoute)
747 {
748     Ip6::Nd::RouterAdvertMessage::Header header;
749     uint16_t                             length;
750 
751     header.SetRouterLifetime(aDefaultRoute.mLifetime);
752     header.SetDefaultRouterPreference(aDefaultRoute.mPreference);
753 
754     {
755         Ip6::Nd::RouterAdvertMessage raMsg(header, aBuffer);
756 
757         for (; aNumPios > 0; aPios++, aNumPios--)
758         {
759             SuccessOrQuit(
760                 raMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime));
761         }
762 
763         for (; aNumRios > 0; aRios++, aNumRios--)
764         {
765             SuccessOrQuit(raMsg.AppendRouteInfoOption(aRios->mPrefix, aRios->mValidLifetime, aRios->mPreference));
766         }
767 
768         length = raMsg.GetAsPacket().GetLength();
769     }
770 
771     return length;
772 }
773 
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Pio * aPios,uint16_t aNumPios,const Rio * aRios,uint16_t aNumRios,const DefaultRoute & aDefaultRoute)774 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
775                       const Pio          *aPios,
776                       uint16_t            aNumPios,
777                       const Rio          *aRios,
778                       uint16_t            aNumRios,
779                       const DefaultRoute &aDefaultRoute)
780 {
781     uint8_t  buffer[kMaxRaSize];
782     uint16_t length = BuildRouterAdvert(buffer, aPios, aNumPios, aRios, aNumRios, aDefaultRoute);
783 
784     SendRouterAdvert(aRouterAddress, buffer, length);
785     Log("Sending RA from router %s", aRouterAddress.ToString().AsCString());
786     LogRouterAdvert(buffer, length);
787 }
788 
789 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))790 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
791                       const Pio (&aPios)[kNumPios],
792                       const Rio (&aRios)[kNumRios],
793                       const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium))
794 {
795     SendRouterAdvert(aRouterAddress, aPios, kNumPios, aRios, kNumRios, aDefaultRoute);
796 }
797 
798 template <uint16_t kNumPios>
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Pio (& aPios)[kNumPios],const DefaultRoute & aDefaultRoute=DefaultRoute (0,NetworkData::kRoutePreferenceMedium))799 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
800                       const Pio (&aPios)[kNumPios],
801                       const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium))
802 {
803     SendRouterAdvert(aRouterAddress, aPios, kNumPios, nullptr, 0, aDefaultRoute);
804 }
805 
806 template <uint16_t kNumRios>
SendRouterAdvert(const Ip6::Address & aRouterAddress,const Rio (& aRios)[kNumRios],const DefaultRoute & aDefaultRoute=DefaultRoute (0,NetworkData::kRoutePreferenceMedium))807 void SendRouterAdvert(const Ip6::Address &aRouterAddress,
808                       const Rio (&aRios)[kNumRios],
809                       const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium))
810 {
811     SendRouterAdvert(aRouterAddress, nullptr, 0, aRios, kNumRios, aDefaultRoute);
812 }
813 
SendRouterAdvert(const Ip6::Address & aRouterAddress,const DefaultRoute & aDefaultRoute)814 void SendRouterAdvert(const Ip6::Address &aRouterAddress, const DefaultRoute &aDefaultRoute)
815 {
816     SendRouterAdvert(aRouterAddress, nullptr, 0, nullptr, 0, aDefaultRoute);
817 }
818 
SendRouterAdvertToBorderRoutingProcessIcmp6Ra(const Pio (& aPios)[kNumPios])819 template <uint16_t kNumPios> void SendRouterAdvertToBorderRoutingProcessIcmp6Ra(const Pio (&aPios)[kNumPios])
820 {
821     uint8_t  buffer[kMaxRaSize];
822     uint16_t length =
823         BuildRouterAdvert(buffer, aPios, kNumPios, nullptr, 0, DefaultRoute(0, NetworkData::kRoutePreferenceMedium));
824 
825     otPlatBorderRoutingProcessIcmp6Ra(sInstance, buffer, length);
826     Log("Passing RA to otPlatBorderRoutingProcessIcmp6Ra");
827     LogRouterAdvert(buffer, length);
828 }
829 
830 struct OnLinkPrefix : public Pio
831 {
OnLinkPrefixOnLinkPrefix832     OnLinkPrefix(const Ip6::Prefix  &aPrefix,
833                  uint32_t            aValidLifetime,
834                  uint32_t            aPreferredLifetime,
835                  const Ip6::Address &aRouterAddress)
836         : Pio(aPrefix, aValidLifetime, aPreferredLifetime)
837         , mRouterAddress(aRouterAddress)
838     {
839     }
840 
841     const Ip6::Address &mRouterAddress;
842 };
843 
844 struct RoutePrefix : public Rio
845 {
RoutePrefixRoutePrefix846     RoutePrefix(const Ip6::Prefix  &aPrefix,
847                 uint32_t            aValidLifetime,
848                 RoutePreference     aPreference,
849                 const Ip6::Address &aRouterAddress)
850         : Rio(aPrefix, aValidLifetime, aPreference)
851         , mRouterAddress(aRouterAddress)
852     {
853     }
854 
855     const Ip6::Address &mRouterAddress;
856 };
857 
858 template <uint16_t kNumOnLinkPrefixes, uint16_t kNumRoutePrefixes>
VerifyPrefixTable(const OnLinkPrefix (& aOnLinkPrefixes)[kNumOnLinkPrefixes],const RoutePrefix (& aRoutePrefixes)[kNumRoutePrefixes])859 void VerifyPrefixTable(const OnLinkPrefix (&aOnLinkPrefixes)[kNumOnLinkPrefixes],
860                        const RoutePrefix (&aRoutePrefixes)[kNumRoutePrefixes])
861 {
862     VerifyPrefixTable(aOnLinkPrefixes, kNumOnLinkPrefixes, aRoutePrefixes, kNumRoutePrefixes);
863 }
864 
VerifyPrefixTable(const OnLinkPrefix (& aOnLinkPrefixes)[kNumOnLinkPrefixes])865 template <uint16_t kNumOnLinkPrefixes> void VerifyPrefixTable(const OnLinkPrefix (&aOnLinkPrefixes)[kNumOnLinkPrefixes])
866 {
867     VerifyPrefixTable(aOnLinkPrefixes, kNumOnLinkPrefixes, nullptr, 0);
868 }
869 
VerifyPrefixTable(const RoutePrefix (& aRoutePrefixes)[kNumRoutePrefixes])870 template <uint16_t kNumRoutePrefixes> void VerifyPrefixTable(const RoutePrefix (&aRoutePrefixes)[kNumRoutePrefixes])
871 {
872     VerifyPrefixTable(nullptr, 0, aRoutePrefixes, kNumRoutePrefixes);
873 }
874 
VerifyPrefixTable(const OnLinkPrefix * aOnLinkPrefixes,uint16_t aNumOnLinkPrefixes,const RoutePrefix * aRoutePrefixes,uint16_t aNumRoutePrefixes)875 void VerifyPrefixTable(const OnLinkPrefix *aOnLinkPrefixes,
876                        uint16_t            aNumOnLinkPrefixes,
877                        const RoutePrefix  *aRoutePrefixes,
878                        uint16_t            aNumRoutePrefixes)
879 {
880     BorderRouter::RoutingManager::PrefixTableIterator iter;
881     BorderRouter::RoutingManager::PrefixTableEntry    entry;
882     uint16_t                                          onLinkPrefixCount = 0;
883     uint16_t                                          routePrefixCount  = 0;
884 
885     Log("VerifyPrefixTable()");
886 
887     sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
888 
889     while (sInstance->Get<BorderRouter::RoutingManager>().GetNextPrefixTableEntry(iter, entry) == kErrorNone)
890     {
891         bool didFind = false;
892 
893         if (entry.mIsOnLink)
894         {
895             Log("   on-link prefix:%s, valid:%u, preferred:%u, router:%s, age:%u",
896                 AsCoreType(&entry.mPrefix).ToString().AsCString(), entry.mValidLifetime, entry.mPreferredLifetime,
897                 AsCoreType(&entry.mRouterAddress).ToString().AsCString(), entry.mMsecSinceLastUpdate / 1000);
898 
899             onLinkPrefixCount++;
900 
901             for (uint16_t index = 0; index < aNumOnLinkPrefixes; index++)
902             {
903                 const OnLinkPrefix &onLinkPrefix = aOnLinkPrefixes[index];
904 
905                 if ((onLinkPrefix.mPrefix == AsCoreType(&entry.mPrefix)) &&
906                     (AsCoreType(&entry.mRouterAddress) == onLinkPrefix.mRouterAddress))
907                 {
908                     VerifyOrQuit(entry.mValidLifetime == onLinkPrefix.mValidLifetime);
909                     VerifyOrQuit(entry.mPreferredLifetime == onLinkPrefix.mPreferredLifetime);
910                     didFind = true;
911                     break;
912                 }
913             }
914         }
915         else
916         {
917             Log("   route prefix:%s, valid:%u, prf:%s, router:%s, age:%u",
918                 AsCoreType(&entry.mPrefix).ToString().AsCString(), entry.mValidLifetime,
919                 PreferenceToString(entry.mRoutePreference), AsCoreType(&entry.mRouterAddress).ToString().AsCString(),
920                 entry.mMsecSinceLastUpdate / 1000);
921 
922             routePrefixCount++;
923 
924             for (uint16_t index = 0; index < aNumRoutePrefixes; index++)
925             {
926                 const RoutePrefix &routePrefix = aRoutePrefixes[index];
927 
928                 if ((routePrefix.mPrefix == AsCoreType(&entry.mPrefix)) &&
929                     (AsCoreType(&entry.mRouterAddress) == routePrefix.mRouterAddress))
930                 {
931                     VerifyOrQuit(entry.mValidLifetime == routePrefix.mValidLifetime);
932                     VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == routePrefix.mPreference);
933                     didFind = true;
934                     break;
935                 }
936             }
937         }
938 
939         VerifyOrQuit(didFind);
940     }
941 
942     VerifyOrQuit(onLinkPrefixCount == aNumOnLinkPrefixes);
943     VerifyOrQuit(routePrefixCount == aNumRoutePrefixes);
944 }
945 
VerifyPrefixTableIsEmpty(void)946 void VerifyPrefixTableIsEmpty(void) { VerifyPrefixTable(nullptr, 0, nullptr, 0); }
947 
InitTest(bool aEnablBorderRouting=false,bool aAfterReset=false)948 void InitTest(bool aEnablBorderRouting = false, bool aAfterReset = false)
949 {
950     uint32_t delay = 10000;
951 
952     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
953     // Initialize OT instance.
954 
955     sNow      = 0;
956     sAlarmOn  = false;
957     sInstance = static_cast<Instance *>(testInitInstance());
958 
959     if (aAfterReset)
960     {
961         delay += 26000; // leader reset sync delay
962     }
963 
964     memset(&sRadioTxFrame, 0, sizeof(sRadioTxFrame));
965     sRadioTxFrame.mPsdu = sRadioTxFramePsdu;
966     sRadioTxOngoing     = false;
967 
968     SuccessOrQuit(sInfraIfAddress.FromString(kInfraIfAddress));
969 
970     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
971     // Initialize and start Border Router and Thread operation.
972 
973     SuccessOrQuit(otBorderRoutingInit(sInstance, kInfraIfIndex, /* aInfraIfIsRunning */ true));
974 
975     otOperationalDatasetTlvs datasetTlvs;
976 
977     SuccessOrQuit(otDatasetConvertToTlvs(&kDataset, &datasetTlvs));
978     SuccessOrQuit(otDatasetSetActiveTlvs(sInstance, &datasetTlvs));
979 
980     SuccessOrQuit(otIp6SetEnabled(sInstance, true));
981     SuccessOrQuit(otThreadSetEnabled(sInstance, true));
982     SuccessOrQuit(otBorderRoutingSetEnabled(sInstance, aEnablBorderRouting));
983 
984     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
985     // Ensure device starts as leader.
986 
987     AdvanceTime(delay);
988 
989     VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
990 
991     // Reset all test flags
992     sRsEmitted   = false;
993     sRaValidated = false;
994     sExpectedPio = kNoPio;
995     sExpectedRios.Clear();
996     sRespondToNs = true;
997 }
998 
FinalizeTest(void)999 void FinalizeTest(void)
1000 {
1001     SuccessOrQuit(otIp6SetEnabled(sInstance, false));
1002     SuccessOrQuit(otThreadSetEnabled(sInstance, false));
1003     SuccessOrQuit(otInstanceErasePersistentInfo(sInstance));
1004     testFreeInstance(sInstance);
1005 }
1006 
1007 //---------------------------------------------------------------------------------------------------------------------
1008 
TestSamePrefixesFromMultipleRouters(void)1009 void TestSamePrefixesFromMultipleRouters(void)
1010 {
1011     Ip6::Prefix  localOnLink;
1012     Ip6::Prefix  localOmr;
1013     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
1014     Ip6::Prefix  routePrefix    = PrefixFromString("2000:1234:5678::", 64);
1015     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
1016     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
1017 
1018     Log("--------------------------------------------------------------------------------------------");
1019     Log("TestSamePrefixesFromMultipleRouters");
1020 
1021     InitTest();
1022 
1023     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1024     // Start Routing Manager. Check emitted RS and RA messages.
1025 
1026     sRsEmitted   = false;
1027     sRaValidated = false;
1028     sExpectedPio = kPioAdvertisingLocalOnLink;
1029     sExpectedRios.Clear();
1030 
1031     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1032 
1033     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1034     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1035 
1036     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1037     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1038 
1039     sExpectedRios.Add(localOmr);
1040 
1041     AdvanceTime(30000);
1042 
1043     VerifyOrQuit(sRsEmitted);
1044     VerifyOrQuit(sRaValidated);
1045     VerifyOrQuit(sExpectedRios.SawAll());
1046     Log("Received RA was validated");
1047 
1048     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1049     // Check Network Data to include the local OMR and on-link prefix.
1050 
1051     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1052     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1053 
1054     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1055     // Send an RA from router A with a new on-link (PIO) and route prefix (RIO).
1056 
1057     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
1058                      {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1059 
1060     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1061     // Check that the local on-link prefix is now deprecating in the new RA.
1062 
1063     sRaValidated = false;
1064     sExpectedPio = kPioDeprecatingLocalOnLink;
1065 
1066     AdvanceTime(10000);
1067     VerifyOrQuit(sRaValidated);
1068 
1069     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1070     // Check the discovered prefix table and ensure info from router A
1071     // is present in the table.
1072 
1073     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1074                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1075 
1076     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1077     // Check Network Data to include new prefixes from router A.
1078 
1079     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
1080     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1081 
1082     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1083     // Send the same RA again from router A with the on-link (PIO) and route prefix (RIO).
1084 
1085     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
1086                      {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1087 
1088     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1089     // Check the discovered prefix table and ensure info from router A
1090     // remains unchanged.
1091 
1092     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1093                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1094 
1095     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1096     // Send an RA from router B with same route prefix (RIO) but with
1097     // high route preference.
1098 
1099     SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
1100 
1101     AdvanceTime(10000);
1102 
1103     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1104     // Check the discovered prefix table and ensure info from router B
1105     // is also included in the table.
1106 
1107     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1108                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA),
1109                        RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
1110 
1111     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1112     // Check Network Data.
1113 
1114     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
1115     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1116 
1117     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1118     // Send an RA from router B removing the route prefix.
1119 
1120     SendRouterAdvert(routerAddressB, {Rio(routePrefix, 0, NetworkData::kRoutePreferenceHigh)});
1121 
1122     AdvanceTime(10000);
1123 
1124     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1125     // Check the discovered prefix table and ensure info from router B
1126     // is now removed from the table.
1127 
1128     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
1129                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1130 
1131     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1132     // Check Network Data.
1133 
1134     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1135 
1136     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1137 
1138     Log("End of TestSamePrefixesFromMultipleRouters");
1139 
1140     FinalizeTest();
1141 }
1142 
TestOmrSelection(void)1143 void TestOmrSelection(void)
1144 {
1145     Ip6::Prefix                     localOnLink;
1146     Ip6::Prefix                     localOmr;
1147     Ip6::Prefix                     omrPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
1148     NetworkData::OnMeshPrefixConfig prefixConfig;
1149 
1150     Log("--------------------------------------------------------------------------------------------");
1151     Log("TestOmrSelection");
1152 
1153     InitTest();
1154 
1155     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1156     // Start Routing Manager. Check emitted RS and RA messages.
1157 
1158     sRsEmitted   = false;
1159     sRaValidated = false;
1160     sExpectedPio = kPioAdvertisingLocalOnLink;
1161     sExpectedRios.Clear();
1162 
1163     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1164 
1165     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1166     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1167 
1168     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1169     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1170 
1171     sExpectedRios.Add(localOmr);
1172 
1173     AdvanceTime(30000);
1174 
1175     VerifyOrQuit(sRsEmitted);
1176     VerifyOrQuit(sRaValidated);
1177     VerifyOrQuit(sExpectedRios.SawAll());
1178     Log("Received RA was validated");
1179 
1180     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1181     // Check Network Data to include the local OMR and on-link prefix.
1182 
1183     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1184     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1185 
1186     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1187     // Add a new OMR prefix directly into net data. The new prefix should
1188     // be favored over the local OMR prefix.
1189 
1190     prefixConfig.Clear();
1191     prefixConfig.mPrefix       = omrPrefix;
1192     prefixConfig.mStable       = true;
1193     prefixConfig.mSlaac        = true;
1194     prefixConfig.mPreferred    = true;
1195     prefixConfig.mOnMesh       = true;
1196     prefixConfig.mDefaultRoute = false;
1197     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1198 
1199     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1200     SuccessOrQuit(otBorderRouterRegister(sInstance));
1201 
1202     AdvanceTime(100);
1203 
1204     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1205     // Make sure BR emits RA with new OMR prefix now.
1206 
1207     sRaValidated = false;
1208     sExpectedPio = kPioAdvertisingLocalOnLink;
1209     sExpectedRios.Clear();
1210     sExpectedRios.Add(omrPrefix);
1211 
1212     AdvanceTime(20000);
1213 
1214     VerifyOrQuit(sRaValidated);
1215     VerifyOrQuit(sExpectedRios.SawAll());
1216 
1217     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1218     // Check Network Data. We should now see that the local OMR prefix
1219     // is removed.
1220 
1221     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ false);
1222     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1223 
1224     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1225     // Remove the OMR prefix previously added in net data.
1226 
1227     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &omrPrefix));
1228     SuccessOrQuit(otBorderRouterRegister(sInstance));
1229 
1230     AdvanceTime(100);
1231 
1232     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1233     // Make sure BR emits RA with local OMR prefix again.
1234 
1235     sRaValidated = false;
1236     sExpectedRios.Clear();
1237     sExpectedRios.Add(localOmr);
1238 
1239     AdvanceTime(20000);
1240 
1241     VerifyOrQuit(sRaValidated);
1242     VerifyOrQuit(sExpectedRios.SawAll());
1243 
1244     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1245     // Check Network Data. We should see that the local OMR prefix is
1246     // added again.
1247 
1248     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1249     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1250 
1251     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1252 
1253     Log("End of TestOmrSelection");
1254     FinalizeTest();
1255 }
1256 
TestDefaultRoute(void)1257 void TestDefaultRoute(void)
1258 {
1259     Ip6::Prefix                     localOnLink;
1260     Ip6::Prefix                     localOmr;
1261     Ip6::Prefix                     omrPrefix      = PrefixFromString("2000:0000:1111:4444::", 64);
1262     Ip6::Prefix                     defaultRoute   = PrefixFromString("::", 0);
1263     Ip6::Address                    routerAddressA = AddressFromString("fd00::aaaa");
1264     NetworkData::OnMeshPrefixConfig prefixConfig;
1265 
1266     Log("--------------------------------------------------------------------------------------------");
1267     Log("TestDefaultRoute");
1268 
1269     InitTest();
1270 
1271     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1272     // Start Routing Manager. Check emitted RS and RA messages.
1273 
1274     sRsEmitted   = false;
1275     sRaValidated = false;
1276     sExpectedPio = kPioAdvertisingLocalOnLink;
1277     sExpectedRios.Clear();
1278 
1279     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1280 
1281     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1282     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1283 
1284     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1285     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1286 
1287     sExpectedRios.Add(localOmr);
1288 
1289     AdvanceTime(30000);
1290 
1291     VerifyOrQuit(sRsEmitted);
1292     VerifyOrQuit(sRaValidated);
1293     VerifyOrQuit(sExpectedRios.SawAll());
1294     Log("Received RA was validated");
1295 
1296     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1297     // Check Network Data to include the local OMR and ULA prefix.
1298 
1299     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1300     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1301 
1302     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1303     // Send RA from router A advertising a default route.
1304 
1305     SendRouterAdvert(routerAddressA, DefaultRoute(kValidLitime, NetworkData::kRoutePreferenceLow));
1306 
1307     AdvanceTime(10000);
1308 
1309     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1310     // Check the discovered prefix table and ensure default route
1311     // from router A is in the table.
1312 
1313     VerifyPrefixTable({RoutePrefix(defaultRoute, kValidLitime, NetworkData::kRoutePreferenceLow, routerAddressA)});
1314 
1315     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1316     // Check Network Data. We should not see default route in
1317     // Network Data yet since there is no infrastructure-derived
1318     // OMR prefix (with preference medium or higher).
1319 
1320     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1321     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1322 
1323     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1324     // Add an OMR prefix directly into Network Data with
1325     // preference medium (infrastructure-derived).
1326 
1327     prefixConfig.Clear();
1328     prefixConfig.mPrefix       = omrPrefix;
1329     prefixConfig.mStable       = true;
1330     prefixConfig.mSlaac        = true;
1331     prefixConfig.mPreferred    = true;
1332     prefixConfig.mOnMesh       = true;
1333     prefixConfig.mDefaultRoute = true;
1334     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1335 
1336     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1337     SuccessOrQuit(otBorderRouterRegister(sInstance));
1338 
1339     AdvanceTime(10000);
1340 
1341     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1342     // Check Network Data. Now that we have an infrastructure-derived
1343     // OMR prefix, the default route should be published.
1344 
1345     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1346     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1347 
1348     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1349     // Remove the OMR prefix from Network Data.
1350 
1351     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &omrPrefix));
1352     SuccessOrQuit(otBorderRouterRegister(sInstance));
1353 
1354     AdvanceTime(10000);
1355 
1356     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1357     // Check Network Data. We should again go back to ULA prefix. The
1358     // default route advertised by router A should be still present in
1359     // the discovered prefix table.
1360 
1361     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1362     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1363 
1364     VerifyPrefixTable({RoutePrefix(defaultRoute, kValidLitime, NetworkData::kRoutePreferenceLow, routerAddressA)});
1365 
1366     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1367     // Add the OMR prefix again.
1368 
1369     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1370     SuccessOrQuit(otBorderRouterRegister(sInstance));
1371 
1372     AdvanceTime(10000);
1373 
1374     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1375     // Check Network Data. Again the default route should be published.
1376 
1377     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1378     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1379 
1380     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1381     // Send RA from router A removing the default route.
1382 
1383     SendRouterAdvert(routerAddressA, DefaultRoute(0, NetworkData::kRoutePreferenceLow));
1384 
1385     AdvanceTime(10000);
1386 
1387     VerifyPrefixTableIsEmpty();
1388 
1389     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1390     // Check Network Data. Now that router A no longer advertised
1391     // a default-route, we should go back to publishing ULA route.
1392 
1393     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1394     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1395 
1396     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1397     // Send RA from router A again advertising a default route.
1398 
1399     SendRouterAdvert(routerAddressA, DefaultRoute(kValidLitime, NetworkData::kRoutePreferenceLow));
1400 
1401     AdvanceTime(10000);
1402 
1403     VerifyPrefixTable({RoutePrefix(defaultRoute, kValidLitime, NetworkData::kRoutePreferenceLow, routerAddressA)});
1404 
1405     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1406     // Check Network Data. We should see default route published.
1407 
1408     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1409     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1410 
1411     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1412 
1413     Log("End of TestDefaultRoute");
1414 
1415     FinalizeTest();
1416 }
1417 
TestAdvNonUlaRoute(void)1418 void TestAdvNonUlaRoute(void)
1419 {
1420     Ip6::Prefix                     localOnLink;
1421     Ip6::Prefix                     localOmr;
1422     Ip6::Prefix                     omrPrefix      = PrefixFromString("2000:0000:1111:4444::", 64);
1423     Ip6::Prefix                     routePrefix    = PrefixFromString("2000:1234:5678::", 64);
1424     Ip6::Address                    routerAddressA = AddressFromString("fd00::aaaa");
1425     NetworkData::OnMeshPrefixConfig prefixConfig;
1426 
1427     Log("--------------------------------------------------------------------------------------------");
1428     Log("TestAdvNonUlaRoute");
1429 
1430     InitTest();
1431 
1432     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1433     // Start Routing Manager. Check emitted RS and RA messages.
1434 
1435     sRsEmitted   = false;
1436     sRaValidated = false;
1437     sExpectedPio = kPioAdvertisingLocalOnLink;
1438     sExpectedRios.Clear();
1439 
1440     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1441 
1442     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1443     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1444 
1445     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1446     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1447 
1448     sExpectedRios.Add(localOmr);
1449 
1450     AdvanceTime(30000);
1451 
1452     VerifyOrQuit(sRsEmitted);
1453     VerifyOrQuit(sRaValidated);
1454     VerifyOrQuit(sExpectedRios.SawAll());
1455     Log("Received RA was validated");
1456 
1457     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1458     // Check Network Data to include the local OMR and ULA prefix.
1459 
1460     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1461     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1462 
1463     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1464     // Send RA from router A advertising a non-ULA.
1465 
1466     SendRouterAdvert(routerAddressA, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1467 
1468     AdvanceTime(10000);
1469 
1470     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1471     // Check the discovered prefix table and ensure the non-ULA
1472     // from router A is in the table.
1473 
1474     VerifyPrefixTable({RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1475 
1476     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1477     // Check Network Data. We should not see default route in
1478     // Network Data yet since there is no infrastructure-derived
1479     // OMR prefix (with preference medium or higher).
1480 
1481     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1482     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1483 
1484     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1485     // Add an OMR prefix directly into Network Data with
1486     // preference medium (infrastructure-derived).
1487 
1488     prefixConfig.Clear();
1489     prefixConfig.mPrefix       = omrPrefix;
1490     prefixConfig.mStable       = true;
1491     prefixConfig.mSlaac        = true;
1492     prefixConfig.mPreferred    = true;
1493     prefixConfig.mOnMesh       = true;
1494     prefixConfig.mDefaultRoute = true;
1495     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1496 
1497     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1498     SuccessOrQuit(otBorderRouterRegister(sInstance));
1499 
1500     AdvanceTime(10000);
1501 
1502     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1503     // Check Network Data. Now that we have an infrastructure-derived
1504     // OMR prefix, the default route should be published.
1505 
1506     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1507     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1508 
1509     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1510     // Remove the OMR prefix from Network Data.
1511 
1512     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &omrPrefix));
1513     SuccessOrQuit(otBorderRouterRegister(sInstance));
1514 
1515     AdvanceTime(10000);
1516 
1517     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1518     // Check Network Data. We should again go back to ULA prefix. The
1519     // non-ULA route advertised by router A should be still present in
1520     // the discovered prefix table.
1521 
1522     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1523     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1524 
1525     VerifyPrefixTable({RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1526 
1527     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1528     // Add the OMR prefix again.
1529 
1530     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1531     SuccessOrQuit(otBorderRouterRegister(sInstance));
1532 
1533     AdvanceTime(10000);
1534 
1535     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1536     // Check Network Data. Again the default route should be published.
1537 
1538     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1539     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1540 
1541     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1542     // Send RA from router A removing the route.
1543 
1544     SendRouterAdvert(routerAddressA, {Rio(routePrefix, 0, NetworkData::kRoutePreferenceMedium)});
1545 
1546     AdvanceTime(10000);
1547 
1548     VerifyPrefixTableIsEmpty();
1549 
1550     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1551     // Check Network Data. Now that router A no longer advertised
1552     // the route, we should go back to publishing the ULA route.
1553 
1554     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1555     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1556 
1557     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1558     // Send RA from router A again advertising the route again.
1559 
1560     SendRouterAdvert(routerAddressA, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
1561 
1562     AdvanceTime(10000);
1563 
1564     VerifyPrefixTable({RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
1565 
1566     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1567     // Check Network Data. We should see default route published.
1568 
1569     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ true);
1570     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
1571 
1572     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1573 
1574     Log("End of TestAdvNonUlaRoute");
1575 
1576     FinalizeTest();
1577 }
1578 
TestLocalOnLinkPrefixDeprecation(void)1579 void TestLocalOnLinkPrefixDeprecation(void)
1580 {
1581     static constexpr uint32_t kMaxRaTxInterval = 601; // In seconds
1582 
1583     Ip6::Prefix  localOnLink;
1584     Ip6::Prefix  localOmr;
1585     Ip6::Prefix  onLinkPrefix   = PrefixFromString("fd00:abba:baba::", 64);
1586     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
1587     uint32_t     localOnLinkLifetime;
1588 
1589     Log("--------------------------------------------------------------------------------------------");
1590     Log("TestLocalOnLinkPrefixDeprecation");
1591 
1592     InitTest();
1593 
1594     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1595     // Start Routing Manager. Check emitted RS and RA messages.
1596 
1597     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1598 
1599     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1600     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1601 
1602     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1603     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1604 
1605     sRsEmitted   = false;
1606     sRaValidated = false;
1607     sExpectedPio = kPioAdvertisingLocalOnLink;
1608     sExpectedRios.Clear();
1609     sExpectedRios.Add(localOmr);
1610 
1611     AdvanceTime(30000);
1612 
1613     VerifyOrQuit(sRsEmitted);
1614     VerifyOrQuit(sRaValidated);
1615     VerifyOrQuit(sExpectedRios.SawAll());
1616     Log("Local on-link prefix is being advertised, lifetime: %d", sOnLinkLifetime);
1617     localOnLinkLifetime = sOnLinkLifetime;
1618 
1619     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1620     // Check Network Data to include the local OMR and on-link prefix.
1621 
1622     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1623     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1624 
1625     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1626     // Send an RA from router A with a new on-link (PIO) which is preferred over
1627     // the local on-link prefix.
1628 
1629     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
1630 
1631     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1632     // Check that the local on-link prefix is now deprecating in the new RA.
1633 
1634     sRaValidated = false;
1635     sExpectedPio = kPioDeprecatingLocalOnLink;
1636     sExpectedRios.Clear();
1637     sExpectedRios.Add(localOmr);
1638 
1639     AdvanceTime(10000);
1640     VerifyOrQuit(sRaValidated);
1641     VerifyOrQuit(sExpectedRios.SawAll());
1642     Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
1643     VerifyOrQuit(sOnLinkLifetime < localOnLinkLifetime);
1644     localOnLinkLifetime = sOnLinkLifetime;
1645 
1646     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1647     // Check Network Data. We must see the new on-link prefix from router A
1648     // along with the deprecating local on-link prefix.
1649 
1650     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1651     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1652 
1653     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1654     // Wait for local on-link prefix to expire
1655 
1656     while (localOnLinkLifetime > kMaxRaTxInterval)
1657     {
1658         // Send same RA from router A to keep the on-link prefix alive.
1659 
1660         SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
1661 
1662         // Ensure Network Data entries remain as before. Mainly we still
1663         // see the deprecating local on-link prefix.
1664 
1665         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1666         VerifyExternalRouteInNetData(kUlaRoute, kSkipAdvPioCheck);
1667 
1668         // Keep checking the emitted RAs and make sure on-link prefix
1669         // is included with smaller lifetime every time.
1670 
1671         sRaValidated = false;
1672         sExpectedPio = kPioDeprecatingLocalOnLink;
1673         sExpectedRios.Clear();
1674         sExpectedRios.Add(localOmr);
1675 
1676         AdvanceTime(kMaxRaTxInterval * 1000);
1677 
1678         VerifyOrQuit(sRaValidated);
1679         VerifyOrQuit(sExpectedRios.SawAll());
1680         Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
1681         VerifyOrQuit(sOnLinkLifetime < localOnLinkLifetime);
1682         localOnLinkLifetime = sOnLinkLifetime;
1683     }
1684 
1685     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1686     // The local on-link prefix must be expired and should no
1687     // longer be seen in the emitted RA message.
1688 
1689     sRaValidated = false;
1690     sExpectedPio = kNoPio;
1691     sExpectedRios.Clear();
1692     sExpectedRios.Add(localOmr);
1693 
1694     AdvanceTime(kMaxRaTxInterval * 1000);
1695 
1696     VerifyOrQuit(sRaValidated);
1697     VerifyOrQuit(sExpectedRios.SawAll());
1698     Log("On-link prefix is now expired");
1699 
1700     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1701     // Check Network Data.
1702 
1703     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1704     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioCleared);
1705 
1706     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1707 
1708     Log("End of TestLocalOnLinkPrefixDeprecation");
1709 
1710     FinalizeTest();
1711 }
1712 
1713 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
TestDomainPrefixAsOmr(void)1714 void TestDomainPrefixAsOmr(void)
1715 {
1716     Ip6::Prefix                     localOnLink;
1717     Ip6::Prefix                     localOmr;
1718     Ip6::Prefix                     domainPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
1719     NetworkData::OnMeshPrefixConfig prefixConfig;
1720 
1721     Log("--------------------------------------------------------------------------------------------");
1722     Log("TestDomainPrefixAsOmr");
1723 
1724     InitTest();
1725 
1726     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1727     // Start Routing Manager. Check emitted RS and RA messages.
1728 
1729     sRsEmitted   = false;
1730     sRaValidated = false;
1731     sExpectedPio = kPioAdvertisingLocalOnLink;
1732     sExpectedRios.Clear();
1733 
1734     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1735 
1736     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1737     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1738 
1739     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1740     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1741 
1742     sExpectedRios.Add(localOmr);
1743 
1744     AdvanceTime(30000);
1745 
1746     VerifyOrQuit(sRsEmitted);
1747     VerifyOrQuit(sRaValidated);
1748     VerifyOrQuit(sExpectedRios.SawAll());
1749     Log("Received RA was validated");
1750 
1751     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1752     // Check Network Data to include the local OMR and on-link prefix.
1753 
1754     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1755     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1756 
1757     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1758     // Add a domain prefix directly into net data. The new prefix should
1759     // be favored over the local OMR prefix.
1760 
1761     otBackboneRouterSetEnabled(sInstance, true);
1762 
1763     prefixConfig.Clear();
1764     prefixConfig.mPrefix       = domainPrefix;
1765     prefixConfig.mStable       = true;
1766     prefixConfig.mSlaac        = true;
1767     prefixConfig.mPreferred    = true;
1768     prefixConfig.mOnMesh       = true;
1769     prefixConfig.mDefaultRoute = false;
1770     prefixConfig.mDp           = true;
1771     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
1772 
1773     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1774     SuccessOrQuit(otBorderRouterRegister(sInstance));
1775 
1776     AdvanceTime(100);
1777 
1778     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1779     // Make sure BR emits RA without domain prefix or previous local OMR.
1780 
1781     sRaValidated = false;
1782     sExpectedPio = kPioAdvertisingLocalOnLink;
1783     sExpectedRios.Clear();
1784     sExpectedRios.Add(domainPrefix);
1785     sExpectedRios.Add(localOmr);
1786 
1787     AdvanceTime(20000);
1788 
1789     VerifyOrQuit(sRaValidated);
1790 
1791     // We should see RIO removing the local OMR prefix with lifetime zero
1792     // and should not see the domain prefix as RIO.
1793 
1794     VerifyOrQuit(sExpectedRios[0].mPrefix == domainPrefix);
1795     VerifyOrQuit(!sExpectedRios[0].mSawInRa);
1796 
1797     VerifyOrQuit(sExpectedRios[1].mPrefix == localOmr);
1798     VerifyOrQuit(sExpectedRios[1].mSawInRa);
1799     VerifyOrQuit(sExpectedRios[1].mLifetime == 0);
1800 
1801     sRaValidated = false;
1802     sExpectedPio = kPioAdvertisingLocalOnLink;
1803     sExpectedRios.Clear();
1804     sExpectedRios.Add(domainPrefix);
1805     sExpectedRios.Add(localOmr);
1806 
1807     // Wait for next RA (650 seconds).
1808 
1809     AdvanceTime(650000);
1810 
1811     VerifyOrQuit(sRaValidated);
1812 
1813     // We should not see either domain prefix or local OMR
1814     // as RIO.
1815 
1816     VerifyOrQuit(!sExpectedRios[0].mSawInRa);
1817     VerifyOrQuit(!sExpectedRios[1].mSawInRa);
1818 
1819     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1820     // Check Network Data. We should now see that the local OMR prefix
1821     // is removed.
1822 
1823     VerifyOmrPrefixInNetData(domainPrefix, /* aDefaultRoute */ false);
1824     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1825 
1826     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1827     // Remove the domain prefix from net data.
1828 
1829     SuccessOrQuit(otBorderRouterRemoveOnMeshPrefix(sInstance, &domainPrefix));
1830     SuccessOrQuit(otBorderRouterRegister(sInstance));
1831 
1832     AdvanceTime(100);
1833 
1834     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1835     // Make sure BR emits RA with local OMR prefix again.
1836 
1837     sRaValidated = false;
1838     sExpectedRios.Clear();
1839     sExpectedRios.Add(localOmr);
1840 
1841     AdvanceTime(20000);
1842 
1843     VerifyOrQuit(sRaValidated);
1844     VerifyOrQuit(sExpectedRios.SawAll());
1845 
1846     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1847     // Check Network Data. We should see that the local OMR prefix is
1848     // added again.
1849 
1850     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1851     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1852 
1853     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1854 
1855     Log("End of TestDomainPrefixAsOmr");
1856     FinalizeTest();
1857 }
1858 #endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
1859 
TestExtPanIdChange(void)1860 void TestExtPanIdChange(void)
1861 {
1862     static constexpr uint32_t kMaxRaTxInterval = 601; // In seconds
1863 
1864     static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
1865     static const otExtendedPanId kExtPanId2 = {{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99, 0x88}};
1866     static const otExtendedPanId kExtPanId3 = {{0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xcd, 0xef}};
1867     static const otExtendedPanId kExtPanId4 = {{0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00}};
1868     static const otExtendedPanId kExtPanId5 = {{0x77, 0x88, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55}};
1869 
1870     Ip6::Prefix          localOnLink;
1871     Ip6::Prefix          oldLocalOnLink;
1872     Ip6::Prefix          localOmr;
1873     Ip6::Prefix          onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
1874     Ip6::Address         routerAddressA = AddressFromString("fd00::aaaa");
1875     uint32_t             oldPrefixLifetime;
1876     Ip6::Prefix          oldPrefixes[4];
1877     otOperationalDataset dataset;
1878 
1879     Log("--------------------------------------------------------------------------------------------");
1880     Log("TestExtPanIdChange");
1881 
1882     InitTest();
1883 
1884     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1885     // Start Routing Manager. Check emitted RS and RA messages.
1886 
1887     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1888 
1889     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1890     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
1891 
1892     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
1893     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
1894 
1895     sRsEmitted   = false;
1896     sRaValidated = false;
1897     sExpectedPio = kPioAdvertisingLocalOnLink;
1898     sExpectedRios.Clear();
1899     sExpectedRios.Add(localOmr);
1900 
1901     AdvanceTime(30000);
1902 
1903     VerifyOrQuit(sRsEmitted);
1904     VerifyOrQuit(sRaValidated);
1905     VerifyOrQuit(sExpectedRios.SawAll());
1906     Log("Local on-link prefix is being advertised, lifetime: %d", sOnLinkLifetime);
1907 
1908     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
1909     // Check behavior when ext PAN ID changes while the local on-link is
1910     // being advertised.
1911 
1912     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1913     // Change the extended PAN ID.
1914 
1915     Log("Changing ext PAN ID");
1916 
1917     oldLocalOnLink    = localOnLink;
1918     oldPrefixLifetime = sOnLinkLifetime;
1919 
1920     sRaValidated = false;
1921     sExpectedPio = kPioAdvertisingLocalOnLink;
1922 
1923     SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
1924 
1925     VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
1926 
1927     dataset.mExtendedPanId = kExtPanId1;
1928     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
1929 
1930     AdvanceTime(500);
1931     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
1932     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
1933         oldLocalOnLink.ToString().AsCString());
1934 
1935     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1936     // Validate the received RA message and that it contains the
1937     // old on-link prefix being deprecated.
1938 
1939     AdvanceTime(30000);
1940 
1941     VerifyOrQuit(sRaValidated);
1942     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
1943     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
1944     oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
1945 
1946     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1947     // Validate Network Data.
1948 
1949     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
1950     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1951 
1952     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1953     // Stop BR and validate that a final RA is emitted deprecating
1954     // both current local on-link prefix and old prefix.
1955 
1956     sRaValidated = false;
1957     sExpectedPio = kPioDeprecatingLocalOnLink;
1958 
1959     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
1960     AdvanceTime(100);
1961 
1962     VerifyOrQuit(sRaValidated);
1963     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
1964     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
1965     oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
1966 
1967     sRaValidated = false;
1968     AdvanceTime(350000);
1969     VerifyOrQuit(!sRaValidated);
1970 
1971     VerifyNoOmrPrefixInNetData();
1972     VerifyExternalRouteInNetData(kNoRoute);
1973 
1974     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1975     // Start BR again and validate old prefix will continue to
1976     // be deprecated.
1977 
1978     sRaValidated = false;
1979     sExpectedPio = kPioAdvertisingLocalOnLink;
1980 
1981     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
1982 
1983     AdvanceTime(300000);
1984     VerifyOrQuit(sRaValidated);
1985     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
1986     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
1987     VerifyOrQuit(oldPrefixLifetime > sDeprecatingPrefixes[0].mLifetime);
1988     oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
1989 
1990     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1991     // Wait for old local on-link prefix to expire.
1992 
1993     while (oldPrefixLifetime > 2 * kMaxRaTxInterval)
1994     {
1995         // Ensure Network Data entries remain as before.
1996 
1997         VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
1998 
1999         // Keep checking the emitted RAs and make sure the prefix
2000         // is included with smaller lifetime every time.
2001 
2002         sRaValidated = false;
2003 
2004         AdvanceTime(kMaxRaTxInterval * 1000);
2005 
2006         VerifyOrQuit(sRaValidated);
2007         VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2008         Log("Old on-link prefix is deprecating, remaining lifetime:%d", sDeprecatingPrefixes[0].mLifetime);
2009         VerifyOrQuit(sDeprecatingPrefixes[0].mLifetime < oldPrefixLifetime);
2010         oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2011     }
2012 
2013     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2014     // The local on-link prefix must be expired now and should no
2015     // longer be seen in the emitted RA message.
2016 
2017     sRaValidated = false;
2018 
2019     AdvanceTime(3 * kMaxRaTxInterval * 1000);
2020 
2021     VerifyOrQuit(sRaValidated);
2022     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2023     Log("Old on-link prefix is now expired");
2024 
2025     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2026     // Validate the Network Data.
2027 
2028     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2029     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2030 
2031     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2032     // Check behavior when ext PAN ID changes while the local on-link is being
2033     // deprecated.
2034 
2035     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2036     // Send an RA from router A with a new on-link (PIO) which is preferred over
2037     // the local on-link prefix.
2038 
2039     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2040 
2041     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2042     // Validate that the local on-link prefix is deprecated.
2043 
2044     sRaValidated = false;
2045     sExpectedPio = kPioDeprecatingLocalOnLink;
2046 
2047     AdvanceTime(30000);
2048 
2049     VerifyOrQuit(sRaValidated);
2050 
2051     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2052     // Change the extended PAN ID.
2053 
2054     oldLocalOnLink    = localOnLink;
2055     oldPrefixLifetime = sOnLinkLifetime;
2056 
2057     dataset.mExtendedPanId = kExtPanId2;
2058     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2059 
2060     AdvanceTime(500);
2061     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2062     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
2063         oldLocalOnLink.ToString().AsCString());
2064 
2065     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2066     // Validate that the old local on-link prefix is still being included
2067     // as PIO in the emitted RA.
2068 
2069     sRaValidated = false;
2070     sExpectedPio = kNoPio;
2071 
2072     AdvanceTime(30000);
2073 
2074     VerifyOrQuit(sRaValidated);
2075     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2076     VerifyOrQuit(sDeprecatingPrefixes[0].mPrefix == oldLocalOnLink);
2077 
2078     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2079     // Validate that Network Data.
2080 
2081     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2082     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2083 
2084     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2085     // Wait for old local on-link prefix to expire.
2086 
2087     while (oldPrefixLifetime > 2 * kMaxRaTxInterval)
2088     {
2089         // Send same RA from router A to keep its on-link prefix alive.
2090 
2091         SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2092 
2093         // Ensure Network Data entries remain as before.
2094 
2095         VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2096 
2097         // Keep checking the emitted RAs and make sure the prefix
2098         // is included with smaller lifetime every time.
2099 
2100         sRaValidated = false;
2101 
2102         AdvanceTime(kMaxRaTxInterval * 1000);
2103 
2104         VerifyOrQuit(sRaValidated);
2105         VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2106         Log("Old on-link prefix is deprecating, remaining lifetime:%d", sDeprecatingPrefixes[0].mLifetime);
2107         VerifyOrQuit(sDeprecatingPrefixes[0].mLifetime < oldPrefixLifetime);
2108         oldPrefixLifetime = sDeprecatingPrefixes[0].mLifetime;
2109     }
2110 
2111     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2112     // The old on-link prefix must be expired now and should no
2113     // longer be seen in the emitted RA message.
2114 
2115     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2116 
2117     sRaValidated = false;
2118 
2119     AdvanceTime(kMaxRaTxInterval * 1000);
2120     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2121     AdvanceTime(kMaxRaTxInterval * 1000);
2122     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2123     AdvanceTime(kMaxRaTxInterval * 1000);
2124 
2125     VerifyOrQuit(sRaValidated);
2126     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2127     Log("Old on-link prefix is now expired");
2128 
2129     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2130     // Validate the Network Data.
2131 
2132     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2133     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2134 
2135     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2136     // Check behavior when ext PAN ID changes while the local on-link is not
2137     // advertised.
2138 
2139     Log("Changing ext PAN ID again");
2140 
2141     oldLocalOnLink = localOnLink;
2142 
2143     sRaValidated = false;
2144     sExpectedPio = kNoPio;
2145 
2146     dataset.mExtendedPanId = kExtPanId3;
2147     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2148 
2149     AdvanceTime(500);
2150     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2151     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
2152         oldLocalOnLink.ToString().AsCString());
2153 
2154     AdvanceTime(35000);
2155     VerifyOrQuit(sRaValidated);
2156     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2157 
2158     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2159     // Validate the Network Data.
2160 
2161     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2162     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2163 
2164     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2165     // Remove the on-link prefix PIO being advertised by router A
2166     // and ensure local on-link prefix is advertised again.
2167 
2168     sRaValidated = false;
2169     sExpectedPio = kPioAdvertisingLocalOnLink;
2170 
2171     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, 0)});
2172 
2173     AdvanceTime(300000);
2174     VerifyOrQuit(sRaValidated);
2175     VerifyOrQuit(sDeprecatingPrefixes.IsEmpty());
2176 
2177     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2178     // Wait for longer than valid lifetime of PIO entry from router A.
2179     // Validate that default route is unpublished from network data.
2180 
2181     AdvanceTime(2000 * 1000);
2182     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2183     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2184 
2185     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2186     // Multiple PAN ID changes and multiple deprecating old prefixes.
2187 
2188     oldPrefixes[0] = localOnLink;
2189 
2190     dataset.mExtendedPanId = kExtPanId2;
2191     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2192 
2193     sRaValidated = false;
2194     sExpectedPio = kPioAdvertisingLocalOnLink;
2195 
2196     AdvanceTime(30000);
2197     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2198     VerifyOrQuit(sRaValidated);
2199     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2200     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2201 
2202     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2203 
2204     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2205     // Change the prefix again. We should see two deprecating prefixes.
2206 
2207     oldPrefixes[1] = localOnLink;
2208 
2209     dataset.mExtendedPanId = kExtPanId1;
2210     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2211 
2212     sRaValidated = false;
2213     sExpectedPio = kPioAdvertisingLocalOnLink;
2214 
2215     AdvanceTime(30000);
2216     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2217     VerifyOrQuit(sRaValidated);
2218     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 2);
2219     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2220     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2221 
2222     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2223 
2224     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2225     // Wait for 15 minutes and then change ext PAN ID again.
2226     // Now we should see three deprecating prefixes.
2227 
2228     AdvanceTime(15 * 60 * 1000);
2229 
2230     oldPrefixes[2] = localOnLink;
2231 
2232     dataset.mExtendedPanId = kExtPanId4;
2233     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2234 
2235     sRaValidated = false;
2236     sExpectedPio = kPioAdvertisingLocalOnLink;
2237 
2238     AdvanceTime(30000);
2239     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2240     VerifyOrQuit(sRaValidated);
2241     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2242     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2243     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2244     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[2]));
2245 
2246     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2247 
2248     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2249     // Change ext PAN ID back to previous value of `kExtPanId1`.
2250     // We should still see three deprecating prefixes and the last prefix
2251     // at `oldPrefixes[2]` should again be treated as local on-link prefix.
2252 
2253     oldPrefixes[3] = localOnLink;
2254 
2255     dataset.mExtendedPanId = kExtPanId1;
2256     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2257 
2258     sRaValidated = false;
2259     sExpectedPio = kPioAdvertisingLocalOnLink;
2260 
2261     AdvanceTime(30000);
2262     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2263     VerifyOrQuit(sRaValidated);
2264     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2265     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2266     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2267     VerifyOrQuit(oldPrefixes[2] == localOnLink);
2268     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[3]));
2269 
2270     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2271 
2272     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2273     // Stop BR and validate the final emitted RA to contain
2274     // all deprecating prefixes.
2275 
2276     sRaValidated = false;
2277     sExpectedPio = kPioDeprecatingLocalOnLink;
2278 
2279     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
2280     AdvanceTime(100);
2281 
2282     VerifyOrQuit(sRaValidated);
2283     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2284     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2285     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2286     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[3]));
2287 
2288     VerifyNoOmrPrefixInNetData();
2289     VerifyExternalRouteInNetData(kNoRoute);
2290 
2291     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2292     // Wait for 15 minutes while BR stays disabled and validate
2293     // there are no emitted RAs. We want to check that deprecating
2294     // prefixes continue to expire while BR is stopped.
2295 
2296     sRaValidated = false;
2297     AdvanceTime(15 * 60 * 1000);
2298 
2299     VerifyOrQuit(!sRaValidated);
2300 
2301     VerifyNoOmrPrefixInNetData();
2302     VerifyExternalRouteInNetData(kNoRoute);
2303 
2304     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2305     // Start BR again, and check that we only see the last deprecating prefix
2306     // at `oldPrefixes[3]` in emitted RA and the other two are expired and
2307     // no longer included as PIO and/or in network data.
2308 
2309     sRaValidated = false;
2310     sExpectedPio = kPioAdvertisingLocalOnLink;
2311 
2312     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2313 
2314     AdvanceTime(30000);
2315 
2316     VerifyOrQuit(sRaValidated);
2317     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2318     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[3]));
2319 
2320     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2321 
2322     //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2323     // Validate the oldest prefix is removed when we have too many
2324     // back-to-back PAN ID changes.
2325 
2326     // Remember the oldest deprecating prefix (associated with `kExtPanId4`).
2327     oldLocalOnLink = oldPrefixes[3];
2328 
2329     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(oldPrefixes[0]));
2330     dataset.mExtendedPanId = kExtPanId2;
2331     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2332     AdvanceTime(30000);
2333 
2334     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(oldPrefixes[1]));
2335     dataset.mExtendedPanId = kExtPanId3;
2336     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2337     AdvanceTime(30000);
2338 
2339     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(oldPrefixes[2]));
2340     dataset.mExtendedPanId = kExtPanId5;
2341     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2342 
2343     sRaValidated = false;
2344 
2345     AdvanceTime(30000);
2346 
2347     VerifyOrQuit(sRaValidated);
2348     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2349     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 3);
2350     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[0]));
2351     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[1]));
2352     VerifyOrQuit(sDeprecatingPrefixes.ContainsMatching(oldPrefixes[2]));
2353     VerifyOrQuit(!sDeprecatingPrefixes.ContainsMatching(oldLocalOnLink));
2354 
2355     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2356 
2357     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2358 
2359     Log("End of TestExtPanIdChange");
2360     FinalizeTest();
2361 }
2362 
TestRouterNsProbe(void)2363 void TestRouterNsProbe(void)
2364 {
2365     Ip6::Prefix  localOnLink;
2366     Ip6::Prefix  localOmr;
2367     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
2368     Ip6::Prefix  routePrefix    = PrefixFromString("2000:1234:5678::", 64);
2369     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
2370     Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
2371 
2372     Log("--------------------------------------------------------------------------------------------");
2373     Log("TestRouterNsProbe");
2374 
2375     InitTest();
2376 
2377     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2378     // Start Routing Manager. Check emitted RS and RA messages.
2379 
2380     sRsEmitted   = false;
2381     sRaValidated = false;
2382     sExpectedPio = kPioAdvertisingLocalOnLink;
2383     sExpectedRios.Clear();
2384 
2385     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2386 
2387     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2388     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2389 
2390     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2391     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2392 
2393     sExpectedRios.Add(localOmr);
2394 
2395     AdvanceTime(30000);
2396 
2397     VerifyOrQuit(sRsEmitted);
2398     VerifyOrQuit(sRaValidated);
2399     VerifyOrQuit(sExpectedRios.SawAll());
2400     Log("Received RA was validated");
2401 
2402     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2403     // Send an RA from router A with a new on-link (PIO) and route prefix (RIO).
2404 
2405     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
2406                      {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
2407 
2408     sExpectedPio = kPioDeprecatingLocalOnLink;
2409 
2410     AdvanceTime(10);
2411 
2412     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2413     // Check the discovered prefix table and ensure info from router A
2414     // is present in the table.
2415 
2416     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
2417                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
2418 
2419     AdvanceTime(30000);
2420 
2421     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2422     // Send an RA from router B with same route prefix (RIO) but with
2423     // high route preference.
2424 
2425     SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
2426 
2427     AdvanceTime(200);
2428 
2429     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2430     // Check the discovered prefix table and ensure entries from
2431     // both router A and B are seen.
2432 
2433     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
2434                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA),
2435                        RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
2436 
2437     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2438     // Check that BR emitted an NS to ensure routers are active.
2439 
2440     sNsEmitted = false;
2441     sRsEmitted = false;
2442 
2443     AdvanceTime(160 * 1000);
2444 
2445     VerifyOrQuit(sNsEmitted);
2446     VerifyOrQuit(!sRsEmitted);
2447 
2448     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2449     // Disallow responding to NS message.
2450     //
2451     // This should trigger `RoutingManager` to send RS (which will get
2452     // no response as well) and then remove all router entries.
2453 
2454     sRespondToNs = false;
2455 
2456     sExpectedPio = kPioAdvertisingLocalOnLink;
2457     sRaValidated = false;
2458     sNsEmitted   = false;
2459 
2460     AdvanceTime(240 * 1000);
2461 
2462     VerifyOrQuit(sNsEmitted);
2463     VerifyOrQuit(sRaValidated);
2464 
2465     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2466     // Check the discovered prefix table. We should see the on-link entry from
2467     // router A as deprecated and no route prefix.
2468 
2469     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, 0, routerAddressA)});
2470 
2471     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2472     // Verify that no more NS is being sent (since there is no more valid
2473     // router entry in the table).
2474 
2475     sExpectedPio = kPioAdvertisingLocalOnLink;
2476     sRaValidated = false;
2477     sNsEmitted   = false;
2478 
2479     AdvanceTime(6 * 60 * 1000);
2480 
2481     VerifyOrQuit(!sNsEmitted);
2482 
2483     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2484     // Send an RA from router B and verify that we see router B
2485     // entry in prefix table.
2486 
2487     SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
2488 
2489     VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, 0, routerAddressA)},
2490                       {RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
2491 
2492     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2493     // Wait for longer than router active time before NS probe.
2494     // Check again that NS are sent again.
2495 
2496     sRespondToNs = true;
2497     sNsEmitted   = false;
2498     sRsEmitted   = false;
2499 
2500     AdvanceTime(3 * 60 * 1000);
2501 
2502     VerifyOrQuit(sNsEmitted);
2503     VerifyOrQuit(!sRsEmitted);
2504 
2505     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2506 
2507     Log("End of TestRouterNsProbe");
2508     FinalizeTest();
2509 }
2510 
TestConflictingPrefix(void)2511 void TestConflictingPrefix(void)
2512 {
2513     static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
2514 
2515     Ip6::Prefix          localOnLink;
2516     Ip6::Prefix          oldLocalOnLink;
2517     Ip6::Prefix          localOmr;
2518     Ip6::Prefix          onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
2519     Ip6::Address         routerAddressA = AddressFromString("fd00::aaaa");
2520     Ip6::Address         routerAddressB = AddressFromString("fd00::bbbb");
2521     otOperationalDataset dataset;
2522 
2523     Log("--------------------------------------------------------------------------------------------");
2524     Log("TestConflictingPrefix");
2525 
2526     InitTest();
2527 
2528     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2529     // Start Routing Manager. Check emitted RS and RA messages.
2530 
2531     sRsEmitted   = false;
2532     sRaValidated = false;
2533     sExpectedPio = kPioAdvertisingLocalOnLink;
2534     sExpectedRios.Clear();
2535 
2536     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2537 
2538     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2539     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2540 
2541     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2542     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2543 
2544     sExpectedRios.Add(localOmr);
2545 
2546     AdvanceTime(30000);
2547 
2548     VerifyOrQuit(sRsEmitted);
2549     VerifyOrQuit(sRaValidated);
2550     VerifyOrQuit(sExpectedRios.SawAll());
2551     Log("Received RA was validated");
2552 
2553     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2554     // Check Network Data to include the local OMR and on-link prefix.
2555 
2556     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2557     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2558 
2559     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2560     // Send an RA from router A with our local on-link prefix as RIO.
2561 
2562     Log("Send RA from router A with local on-link as RIO");
2563     SendRouterAdvert(routerAddressA, {Rio(localOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
2564 
2565     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2566     // Check that the local on-link prefix is still being advertised.
2567 
2568     sRaValidated = false;
2569     AdvanceTime(610000);
2570     VerifyOrQuit(sRaValidated);
2571 
2572     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2573     // Check Network Data to still include the local OMR and ULA prefix.
2574 
2575     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2576     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2577 
2578     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2579     // Send an RA from router A removing local on-link prefix as RIO.
2580 
2581     SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
2582 
2583     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2584     // Verify that ULA prefix is still included in Network Data and
2585     // the change by router A did not cause it to be unpublished.
2586 
2587     AdvanceTime(10000);
2588     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2589 
2590     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2591     // Check that the local on-link prefix is still being advertised.
2592 
2593     sRaValidated = false;
2594     AdvanceTime(610000);
2595     VerifyOrQuit(sRaValidated);
2596 
2597     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2598 
2599     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2600     // Send RA from router B advertising an on-link prefix. This
2601     // should cause local on-link prefix to be deprecated.
2602 
2603     SendRouterAdvert(routerAddressB, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2604 
2605     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2606     // Check that the local on-link prefix is now deprecating.
2607 
2608     sRaValidated = false;
2609     sExpectedPio = kPioDeprecatingLocalOnLink;
2610 
2611     AdvanceTime(10000);
2612     VerifyOrQuit(sRaValidated);
2613     VerifyOrQuit(sExpectedRios.SawAll());
2614     Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
2615 
2616     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2617     // Check Network Data to include the default route now due
2618     // the new on-link prefix from router B.
2619 
2620     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
2621     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2622 
2623     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2624     // Send an RA from router A again adding local on-link prefix as RIO.
2625 
2626     Log("Send RA from router A with local on-link as RIO");
2627     SendRouterAdvert(routerAddressA, {Rio(localOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
2628 
2629     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2630     // Check that the local on-link prefix is still being deprecated.
2631 
2632     sRaValidated = false;
2633     AdvanceTime(610000);
2634     VerifyOrQuit(sRaValidated);
2635 
2636     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2637     // Check Network Data remains unchanged.
2638 
2639     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2640 
2641     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2642     // Send an RA from router A removing the previous RIO.
2643 
2644     SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
2645 
2646     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2647     // Check Network Data remains unchanged.
2648 
2649     AdvanceTime(60000);
2650     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2651 
2652     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2653     // Send RA from router B removing its on-link prefix.
2654 
2655     SendRouterAdvert(routerAddressB, {Pio(onLinkPrefix, kValidLitime, 0)});
2656 
2657     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2658     // Check that the local on-link prefix is once again being advertised.
2659 
2660     sRaValidated = false;
2661     sExpectedPio = kPioAdvertisingLocalOnLink;
2662 
2663     AdvanceTime(10000);
2664     VerifyOrQuit(sRaValidated);
2665 
2666     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2667     // Check Network Data to remain unchanged.
2668 
2669     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2670 
2671     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2672     // Change the extended PAN ID.
2673 
2674     Log("Changing ext PAN ID");
2675 
2676     SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
2677 
2678     VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
2679 
2680     dataset.mExtendedPanId = kExtPanId1;
2681     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2682     AdvanceTime(10000);
2683 
2684     oldLocalOnLink = localOnLink;
2685     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2686 
2687     Log("Local on-link prefix is changed to %s from %s", localOnLink.ToString().AsCString(),
2688         oldLocalOnLink.ToString().AsCString());
2689 
2690     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2691     // Check Network Data contains default route due to the
2692     // deprecating on-link prefix from router B.
2693 
2694     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2695 
2696     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2697     // Send an RA from router A again adding the old local on-link prefix
2698     // as RIO.
2699 
2700     SendRouterAdvert(routerAddressA, {Rio(oldLocalOnLink, kValidLitime, NetworkData::kRoutePreferenceMedium)});
2701 
2702     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2703     // Check Network Data remains unchanged.
2704 
2705     AdvanceTime(10000);
2706     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2707 
2708     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2709     // Send an RA from router A removing the previous RIO.
2710 
2711     SendRouterAdvert(routerAddressA, {Rio(localOnLink, 0, NetworkData::kRoutePreferenceMedium)});
2712 
2713     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2714     // Check Network Data remains unchanged.
2715 
2716     AdvanceTime(10000);
2717     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2718 
2719     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2720 
2721     Log("End of TestConflictingPrefix");
2722 
2723     FinalizeTest();
2724 }
2725 
2726 #if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
TestSavedOnLinkPrefixes(void)2727 void TestSavedOnLinkPrefixes(void)
2728 {
2729     static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
2730 
2731     Ip6::Prefix          localOnLink;
2732     Ip6::Prefix          oldLocalOnLink;
2733     Ip6::Prefix          localOmr;
2734     Ip6::Prefix          onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
2735     Ip6::Address         routerAddressA = AddressFromString("fd00::aaaa");
2736     otOperationalDataset dataset;
2737 
2738     Log("--------------------------------------------------------------------------------------------");
2739     Log("TestSavedOnLinkPrefixes");
2740 
2741     InitTest(/* aEnablBorderRouting */ true);
2742 
2743     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2744     // Check emitted RS and RA messages.
2745 
2746     sRsEmitted   = false;
2747     sRaValidated = false;
2748     sExpectedPio = kPioAdvertisingLocalOnLink;
2749     sExpectedRios.Clear();
2750 
2751     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2752     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2753 
2754     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2755     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2756 
2757     sExpectedRios.Add(localOmr);
2758 
2759     AdvanceTime(30000);
2760 
2761     VerifyOrQuit(sRsEmitted);
2762     VerifyOrQuit(sRaValidated);
2763     VerifyOrQuit(sExpectedRios.SawAll());
2764 
2765     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2766     // Check Network Data to include the local OMR and ULA prefix.
2767 
2768     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2769     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2770 
2771     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2772     // Disable the instance and re-enable it.
2773 
2774     Log("Disabling and re-enabling OT Instance");
2775 
2776     testFreeInstance(sInstance);
2777 
2778     InitTest(/* aEnablBorderRouting */ true, /* aAfterReset */ true);
2779 
2780     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2781 
2782     sExpectedPio = kPioAdvertisingLocalOnLink;
2783 
2784     AdvanceTime(30000);
2785 
2786     VerifyOrQuit(sRsEmitted);
2787     VerifyOrQuit(sRaValidated);
2788     VerifyOrQuit(sExpectedRios.SawAll());
2789 
2790     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2791     // Check Network Data to include the local OMR and ULA prefix.
2792 
2793     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2794     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2795 
2796     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2797     // Send RA from router A advertising an on-link prefix.
2798 
2799     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2800 
2801     sRaValidated = false;
2802     sExpectedPio = kPioDeprecatingLocalOnLink;
2803 
2804     AdvanceTime(30000);
2805 
2806     VerifyOrQuit(sRaValidated);
2807     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 0);
2808 
2809     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2810     // Disable the instance and re-enable it.
2811 
2812     Log("Disabling and re-enabling OT Instance");
2813 
2814     testFreeInstance(sInstance);
2815 
2816     InitTest(/* aEnablBorderRouting */ true, /* aAfterReset */ true);
2817 
2818     sExpectedPio = kPioAdvertisingLocalOnLink;
2819 
2820     AdvanceTime(30000);
2821 
2822     VerifyOrQuit(sRsEmitted);
2823     VerifyOrQuit(sRaValidated);
2824     VerifyOrQuit(sExpectedRios.SawAll());
2825 
2826     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2827     // Check Network Data to include the local OMR and ULA prefix.
2828 
2829     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
2830     VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
2831 
2832     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2833 
2834     Log("Changing ext PAN ID");
2835 
2836     oldLocalOnLink = localOnLink;
2837 
2838     sRaValidated = false;
2839     sExpectedPio = kPioAdvertisingLocalOnLink;
2840 
2841     SuccessOrQuit(otDatasetGetActive(sInstance, &dataset));
2842 
2843     VerifyOrQuit(dataset.mComponents.mIsExtendedPanIdPresent);
2844 
2845     dataset.mExtendedPanId = kExtPanId1;
2846     dataset.mActiveTimestamp.mSeconds++;
2847     SuccessOrQuit(otDatasetSetActive(sInstance, &dataset));
2848 
2849     AdvanceTime(30000);
2850 
2851     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2852     Log("Local on-link prefix changed to %s from %s", localOnLink.ToString().AsCString(),
2853         oldLocalOnLink.ToString().AsCString());
2854 
2855     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2856     // Disable the instance and re-enable it.
2857 
2858     Log("Disabling and re-enabling OT Instance");
2859 
2860     testFreeInstance(sInstance);
2861 
2862     InitTest(/* aEnablBorderRouting */ false, /* aAfterReset */ true);
2863 
2864     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2865     // Start Routing Manager.
2866 
2867     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2868 
2869     AdvanceTime(100);
2870 
2871     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2872     // Send RA from router A advertising an on-link prefix.
2873     // This ensures the local on-link prefix is not advertised, but
2874     // it must be deprecated since it was advertised last time and
2875     // saved in `Settings`.
2876 
2877     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2878 
2879     sRaValidated = false;
2880     sExpectedPio = kPioDeprecatingLocalOnLink;
2881 
2882     AdvanceTime(30000);
2883 
2884     VerifyOrQuit(sRaValidated);
2885     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 1);
2886 
2887     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2888     // Check Network Data to now use default route due to the
2889     // on-link prefix from router A.
2890 
2891     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
2892 
2893     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2894     // Wait for more than 1800 seconds to let the deprecating
2895     // prefixes expire (keep sending RA from router A).
2896 
2897     for (uint16_t index = 0; index < 185; index++)
2898     {
2899         SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2900         AdvanceTime(10 * 1000);
2901     }
2902 
2903     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2904 
2905     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2906     // Disable the instance and re-enable it and restart Routing Manager.
2907 
2908     Log("Disabling and re-enabling OT Instance again");
2909 
2910     testFreeInstance(sInstance);
2911     InitTest(/* aEnablBorderRouting */ false, /* aAfterReset */ true);
2912 
2913     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2914     AdvanceTime(100);
2915 
2916     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2917     // Send RA from router A advertising an on-link prefix.
2918 
2919     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
2920 
2921     sRaValidated = false;
2922     sExpectedPio = kNoPio;
2923 
2924     AdvanceTime(30000);
2925 
2926     VerifyOrQuit(sRaValidated);
2927     VerifyOrQuit(sDeprecatingPrefixes.GetLength() == 0);
2928 
2929     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2930     // Check Network Data still contains the default route.
2931 
2932     VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioCleared);
2933 
2934     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2935 
2936     Log("End of TestSavedOnLinkPrefixes");
2937     FinalizeTest();
2938 }
2939 #endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
2940 
2941 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
TestAutoEnableOfSrpServer(void)2942 void TestAutoEnableOfSrpServer(void)
2943 {
2944     Ip6::Prefix  localOnLink;
2945     Ip6::Prefix  localOmr;
2946     Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
2947     Ip6::Prefix  onLinkPrefix   = PrefixFromString("2000:abba:baba::", 64);
2948 
2949     Log("--------------------------------------------------------------------------------------------");
2950     Log("TestAutoEnableOfSrpServer");
2951 
2952     InitTest();
2953 
2954     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2955     // Check SRP Server state and enable auto-enable mode
2956 
2957     otSrpServerSetAutoEnableMode(sInstance, true);
2958     VerifyOrQuit(otSrpServerIsAutoEnableMode(sInstance));
2959     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
2960 
2961     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2962     // Start Routing Manager. Check emitted RS and RA messages.
2963 
2964     sRsEmitted   = false;
2965     sRaValidated = false;
2966     sExpectedPio = kPioAdvertisingLocalOnLink;
2967     sExpectedRios.Clear();
2968 
2969     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
2970 
2971     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
2972     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
2973 
2974     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
2975     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
2976 
2977     sExpectedRios.Add(localOmr);
2978 
2979     AdvanceTime(30000);
2980 
2981     VerifyOrQuit(sRsEmitted);
2982     VerifyOrQuit(sRaValidated);
2983     VerifyOrQuit(sExpectedRios.SawAll());
2984     Log("Received RA was validated");
2985 
2986     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2987     // Validate that SRP server was auto-enabled
2988 
2989     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
2990     Log("Srp::Server is enabled");
2991 
2992     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2993     // Signal that infra if state changed and is no longer running.
2994     // This should stop Routing Manager and in turn the SRP server.
2995 
2996     sRaValidated = false;
2997     sExpectedPio = kPioDeprecatingLocalOnLink;
2998 
2999     Log("Signal infra if is not running");
3000     SuccessOrQuit(otPlatInfraIfStateChanged(sInstance, kInfraIfIndex, false));
3001     AdvanceTime(1);
3002 
3003     VerifyOrQuit(sRaValidated);
3004 
3005     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3006     // Check that SRP server is disabled.
3007 
3008     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3009     Log("Srp::Server is disabled");
3010 
3011     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3012     // Signal that infra if state changed and is running again.
3013 
3014     sRsEmitted   = false;
3015     sRaValidated = false;
3016     sExpectedPio = kPioAdvertisingLocalOnLink;
3017     sExpectedRios.Add(localOmr);
3018 
3019     Log("Signal infra if is running");
3020     SuccessOrQuit(otPlatInfraIfStateChanged(sInstance, kInfraIfIndex, true));
3021 
3022     AdvanceTime(30000);
3023 
3024     VerifyOrQuit(sRsEmitted);
3025     VerifyOrQuit(sRaValidated);
3026     VerifyOrQuit(sExpectedRios.SawAll());
3027     Log("Received RA was validated");
3028 
3029     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3030     // Check that SRP server is enabled again.
3031 
3032     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3033     Log("Srp::Server is enabled");
3034 
3035     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3036     // Disable `RoutingManager` explicitly.
3037 
3038     sRaValidated = false;
3039     sExpectedPio = kPioDeprecatingLocalOnLink;
3040 
3041     Log("Disabling RoutingManager");
3042     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
3043     AdvanceTime(1);
3044 
3045     VerifyOrQuit(sRaValidated);
3046 
3047     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3048     // Check that SRP server is also disabled.
3049 
3050     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3051     Log("Srp::Server is disabled");
3052 
3053     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3054     // Disable auto-enable mode on SRP server.
3055 
3056     otSrpServerSetAutoEnableMode(sInstance, false);
3057     VerifyOrQuit(!otSrpServerIsAutoEnableMode(sInstance));
3058     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3059 
3060     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3061     // Re-start Routing Manager. Check emitted RS and RA messages.
3062     // This cycle, router A will send a RA including a PIO.
3063 
3064     sRsEmitted   = false;
3065     sRaValidated = false;
3066     sExpectedPio = kNoPio;
3067     sExpectedRios.Clear();
3068 
3069     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3070 
3071     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
3072     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3073 
3074     Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
3075     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3076 
3077     sExpectedRios.Add(localOmr);
3078 
3079     AdvanceTime(2000);
3080 
3081     SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
3082 
3083     AdvanceTime(30000);
3084 
3085     VerifyOrQuit(sRsEmitted);
3086     VerifyOrQuit(sRaValidated);
3087     VerifyOrQuit(sExpectedRios.SawAll());
3088     Log("Received RA was validated");
3089 
3090     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3091     // Check that SRP server is still disabled.
3092 
3093     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3094     Log("Srp::Server is disabled");
3095 
3096     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3097     // Enable auto-enable mode on SRP server. Since `RoutingManager`
3098     // is already done with initial policy evaluation, the SRP server
3099     // must be started immediately.
3100 
3101     otSrpServerSetAutoEnableMode(sInstance, true);
3102     VerifyOrQuit(otSrpServerIsAutoEnableMode(sInstance));
3103 
3104     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3105     Log("Srp::Server is enabled");
3106 
3107     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3108     // Disable auto-enable mode on SRP server. It must not impact
3109     // its current state and it should remain enabled.
3110 
3111     otSrpServerSetAutoEnableMode(sInstance, false);
3112     VerifyOrQuit(!otSrpServerIsAutoEnableMode(sInstance));
3113 
3114     AdvanceTime(2000);
3115     VerifyOrQuit(otSrpServerGetState(sInstance) != OT_SRP_SERVER_STATE_DISABLED);
3116     Log("Srp::Server is enabled");
3117 
3118     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3119     // Signal that infra if state changed and is no longer running.
3120     // This should stop Routing Manager.
3121 
3122     sRaValidated = false;
3123 
3124     Log("Signal infra if is not running");
3125     SuccessOrQuit(otPlatInfraIfStateChanged(sInstance, kInfraIfIndex, false));
3126     AdvanceTime(1);
3127 
3128     VerifyOrQuit(sRaValidated);
3129 
3130     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3131     // Re-enable auto-enable mode on SRP server. Since `RoutingManager`
3132     // is stopped (infra if is down), the SRP serer must be stopped
3133     // immediately.
3134 
3135     otSrpServerSetAutoEnableMode(sInstance, true);
3136     VerifyOrQuit(otSrpServerIsAutoEnableMode(sInstance));
3137 
3138     VerifyOrQuit(otSrpServerGetState(sInstance) == OT_SRP_SERVER_STATE_DISABLED);
3139     Log("Srp::Server is disabled");
3140 
3141     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3142 
3143     Log("End of TestAutoEnableOfSrpServer");
3144     FinalizeTest();
3145 }
3146 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
3147 
3148 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
TestNat64PrefixSelection(void)3149 void TestNat64PrefixSelection(void)
3150 {
3151     Ip6::Prefix                     localNat64;
3152     Ip6::Prefix                     ailNat64 = PrefixFromString("2000:0:0:1:0:0::", 96);
3153     Ip6::Prefix                     localOmr;
3154     Ip6::Prefix                     omrPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
3155     NetworkData::OnMeshPrefixConfig prefixConfig;
3156 
3157     Log("--------------------------------------------------------------------------------------------");
3158     Log("TestNat64PrefixSelection");
3159 
3160     InitTest();
3161 
3162     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3163     // Start Routing Manager. Check local NAT64 prefix generation.
3164 
3165     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
3166     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetNat64Prefix(localNat64));
3167     SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3168 
3169     Log("Local nat64 prefix is %s", localNat64.ToString().AsCString());
3170     Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
3171 
3172     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3173     // Enable Nat64 Prefix Manager. Check local NAT64 prefix in Network Data.
3174 
3175     sInstance->Get<BorderRouter::RoutingManager>().SetNat64PrefixManagerEnabled(true);
3176 
3177     AdvanceTime(20000);
3178 
3179     VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3180     VerifyNat64PrefixInNetData(localNat64);
3181 
3182     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3183     // AIL NAT64 prefix discovered. No infra-derived OMR prefix in Network Data.
3184     // Check local NAT64 prefix in Network Data.
3185 
3186     DiscoverNat64Prefix(ailNat64);
3187 
3188     AdvanceTime(20000);
3189 
3190     VerifyNat64PrefixInNetData(localNat64);
3191 
3192     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3193     // Add a medium preference OMR prefix into Network Data.
3194     // Check AIL NAT64 prefix published in Network Data.
3195 
3196     prefixConfig.Clear();
3197     prefixConfig.mPrefix       = omrPrefix;
3198     prefixConfig.mStable       = true;
3199     prefixConfig.mSlaac        = true;
3200     prefixConfig.mPreferred    = true;
3201     prefixConfig.mOnMesh       = true;
3202     prefixConfig.mDefaultRoute = false;
3203     prefixConfig.mPreference   = NetworkData::kRoutePreferenceMedium;
3204 
3205     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
3206     SuccessOrQuit(otBorderRouterRegister(sInstance));
3207 
3208     AdvanceTime(20000);
3209 
3210     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ false);
3211     VerifyNat64PrefixInNetData(ailNat64);
3212 
3213     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3214     // AIL NAT64 prefix removed.
3215     // Check local NAT64 prefix in Network Data.
3216 
3217     ailNat64.Clear();
3218     DiscoverNat64Prefix(ailNat64);
3219 
3220     AdvanceTime(20000);
3221 
3222     VerifyOmrPrefixInNetData(omrPrefix, /* aDefaultRoute */ false);
3223     VerifyNat64PrefixInNetData(localNat64);
3224 
3225     Log("End of TestNat64PrefixSelection");
3226     FinalizeTest();
3227 }
3228 #endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
3229 
3230 #if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
VerifyPdOmrPrefix(const Ip6::Prefix & aPrefix)3231 void VerifyPdOmrPrefix(const Ip6::Prefix &aPrefix)
3232 {
3233     otBorderRoutingPrefixTableEntry platformPrefixInfo;
3234 
3235     VerifyOrQuit(otBorderRoutingGetPdOmrPrefix(sInstance, &platformPrefixInfo) == OT_ERROR_NONE);
3236     VerifyOrQuit(AsCoreType(&platformPrefixInfo.mPrefix) == aPrefix);
3237 }
3238 
VerifyNoPdOmrPrefix()3239 void VerifyNoPdOmrPrefix()
3240 {
3241     otBorderRoutingPrefixTableEntry platformPrefixInfo;
3242 
3243     VerifyOrQuit(otBorderRoutingGetPdOmrPrefix(sInstance, &platformPrefixInfo) == OT_ERROR_NOT_FOUND);
3244 }
3245 
TestBorderRoutingProcessPlatfromGeneratedNd(void)3246 void TestBorderRoutingProcessPlatfromGeneratedNd(void)
3247 {
3248     Ip6::Prefix localOmr;
3249 
3250     Log("--------------------------------------------------------------------------------------------");
3251     Log("TestBorderRoutingProcessPlatfromGeneratedNd");
3252 
3253     InitTest(/* aEnableBorderRouting */ true);
3254 
3255     otBorderRoutingDhcp6PdSetEnabled(sInstance, true);
3256 
3257     {
3258         SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
3259     }
3260 
3261     // 0. Reject invalid RA.
3262     Log("0. Invalid RA message.");
3263     {
3264         {
3265             const uint8_t testInvalidRaMessage[] = {
3266                 0x86, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3267             };
3268 
3269             otPlatBorderRoutingProcessIcmp6Ra(sInstance, testInvalidRaMessage, sizeof(testInvalidRaMessage));
3270             VerifyNoPdOmrPrefix();
3271         }
3272 
3273         {
3274             const uint8_t testInvalidRaMessage[] = {
3275                 0x87, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3276             };
3277 
3278             otPlatBorderRoutingProcessIcmp6Ra(sInstance, testInvalidRaMessage, sizeof(testInvalidRaMessage));
3279             VerifyNoPdOmrPrefix();
3280         }
3281 
3282         {
3283             const uint8_t testRaMessageWithInvalidPrefix[] = {
3284                 0x86, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3285                 0x03, 0x04, 0x41, 0xc0, 0x00, 0x00, 0x10, 0xe1, 0x00, 0x00, 0x04, 0xd2, 0x00, 0x00, 0x00, 0x00,
3286                 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3287             };
3288 
3289             otPlatBorderRoutingProcessIcmp6Ra(sInstance, testRaMessageWithInvalidPrefix,
3290                                               sizeof(testRaMessageWithInvalidPrefix));
3291             VerifyNoPdOmrPrefix();
3292         }
3293     }
3294 
3295     // 1. Publish a prefix, and wait until it expired.
3296     Log("1. Simple RA message.");
3297     {
3298         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:dead:beef::", 64);
3299 
3300         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
3301 
3302         sExpectedRios.Add(raPrefix);
3303         AdvanceTime(10000);
3304 
3305         VerifyPdOmrPrefix(raPrefix);
3306         VerifyOrQuit(sExpectedRios.SawAll());
3307         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3308 
3309         AdvanceTime(1500000);
3310         sExpectedRios.Clear();
3311         VerifyPdOmrPrefix(raPrefix);
3312         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3313 
3314         AdvanceTime(400000);
3315         // Deprecated prefixes will be removed.
3316         VerifyNoPdOmrPrefix();
3317         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3318     }
3319 
3320     // 1.1. Publish a prefix, and wait until it expired.
3321     //      Multiple prefixes are advertised, only the smallest one will be used.
3322     Log("1.1. RA message with multiple prefixes.");
3323     {
3324         Ip6::Prefix raPrefix    = PrefixFromString("2001:db8:dead:beef::", 64);
3325         Ip6::Prefix ulaRaPrefix = PrefixFromString("fd01:db8:deaf:beef::", 64);
3326 
3327         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(ulaRaPrefix, kValidLitime * 2, kPreferredLifetime * 2),
3328                                                        Pio(raPrefix, kValidLitime, kPreferredLifetime)});
3329 
3330         sExpectedRios.Add(raPrefix);
3331         AdvanceTime(10000);
3332 
3333         VerifyPdOmrPrefix(raPrefix);
3334         VerifyOrQuit(sExpectedRios.SawAll());
3335         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3336 
3337         AdvanceTime(1500000);
3338         sExpectedRios.Clear();
3339         VerifyPdOmrPrefix(raPrefix);
3340         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3341 
3342         AdvanceTime(400000);
3343         // Deprecated prefixes will be removed.
3344         VerifyNoPdOmrPrefix();
3345         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3346     }
3347 
3348     // 2. Publish a prefix, and renew it before it expired.
3349     Log("2. Renew prefix lifetime.");
3350     {
3351         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:1:2::", 64);
3352 
3353         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
3354 
3355         sExpectedRios.Add(raPrefix);
3356         AdvanceTime(10000);
3357 
3358         VerifyPdOmrPrefix(raPrefix);
3359         VerifyOrQuit(sExpectedRios.SawAll());
3360         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3361 
3362         AdvanceTime(1500000);
3363         sExpectedRios.Clear();
3364         VerifyPdOmrPrefix(raPrefix);
3365         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3366 
3367         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
3368 
3369         AdvanceTime(400000);
3370         VerifyPdOmrPrefix(raPrefix);
3371         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3372 
3373         AdvanceTime(1500000);
3374         VerifyNoPdOmrPrefix();
3375         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3376     }
3377 
3378     // 3. Publish a prefix, and publish another prefix to replace it (with goodbye ra).
3379     Log("3. Update prefix.");
3380     {
3381         Ip6::Prefix raPrefix    = PrefixFromString("2001:db8:1:2::", 64);
3382         Ip6::Prefix newRaPrefix = PrefixFromString("2001:db8:3:4::", 64);
3383 
3384         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)});
3385 
3386         sExpectedRios.Add(raPrefix);
3387         sExpectedRios.Clear();
3388         AdvanceTime(10000);
3389 
3390         VerifyPdOmrPrefix(raPrefix);
3391         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3392 
3393         AdvanceTime(1000000);
3394         VerifyPdOmrPrefix(raPrefix);
3395 
3396         SendRouterAdvertToBorderRoutingProcessIcmp6Ra(
3397             {Pio(raPrefix, 0, 0), Pio(newRaPrefix, kValidLitime, kPreferredLifetime)});
3398         sExpectedRios.Add(newRaPrefix);
3399 
3400         AdvanceTime(1000000);
3401         VerifyOrQuit(sExpectedRios.SawAll());
3402         VerifyPdOmrPrefix(newRaPrefix);
3403 
3404         AdvanceTime(1000000);
3405         VerifyNoPdOmrPrefix();
3406         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3407     }
3408 
3409     // 4. Short prefix will be extended to /64.
3410     Log("Short prefix");
3411     {
3412         // The prefix will be padded to a /64 prefix.
3413         Ip6::Prefix raPrefix = PrefixFromString("2001:db8:cafe:0::", 64);
3414         Ip6::Prefix realRaPrefix;
3415 
3416         realRaPrefix.Set(raPrefix.GetBytes(), 48);
3417         SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(realRaPrefix, kValidLitime, kPreferredLifetime)});
3418 
3419         sExpectedRios.Add(raPrefix);
3420         AdvanceTime(10000);
3421 
3422         VerifyPdOmrPrefix(raPrefix);
3423         VerifyOrQuit(sExpectedRios.SawAll());
3424         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3425 
3426         AdvanceTime(1500000);
3427         sExpectedRios.Clear();
3428         VerifyPdOmrPrefix(raPrefix);
3429         VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false);
3430 
3431         AdvanceTime(400000);
3432         // Deprecated prefixes will be removed.
3433         VerifyNoPdOmrPrefix();
3434         VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
3435     }
3436     Log("End of TestBorderRoutingProcessPlatfromGeneratedNd");
3437 }
3438 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
3439 
3440 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
3441 
main(void)3442 int main(void)
3443 {
3444 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
3445     TestSamePrefixesFromMultipleRouters();
3446     TestOmrSelection();
3447     TestDefaultRoute();
3448     TestAdvNonUlaRoute();
3449     TestLocalOnLinkPrefixDeprecation();
3450 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
3451     TestDomainPrefixAsOmr();
3452 #endif
3453     TestExtPanIdChange();
3454     TestConflictingPrefix();
3455     TestRouterNsProbe();
3456 #if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
3457     TestSavedOnLinkPrefixes();
3458 #endif
3459 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
3460     TestAutoEnableOfSrpServer();
3461 #endif
3462 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
3463     TestNat64PrefixSelection();
3464 #endif
3465 #if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
3466     TestBorderRoutingProcessPlatfromGeneratedNd();
3467 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
3468 
3469     printf("All tests passed\n");
3470 #else
3471     printf("BORDER_ROUTING feature is not enabled\n");
3472 #endif
3473 
3474     return 0;
3475 }
3476