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