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