[routing-manager] track all valid PIOs with on-link (L) flag (#11925)

Removes the `IsValidOnLinkPrefix()` helper functions which required a PIO
to have both the on-link (`L`) flag and either the autonomous address
configuration (`A`) or DHCPv6-PD preferred (`P`) flag to be considered
valid.

The `RxRaTracker` is updated to track any received valid PIO as long as
the on-link (`L`) flag is set, regardless of the `A` or `P` flags.

The `OnLinkPrefix` class is updated to store the state of the `A` and
`P` flags from the PIO. These flags are now checked within
`OnLinkPrefix::IsFavoredOver()` to determine if a prefix is eligible
to be a "favored" on-link prefix, but their absence no longer prevents
the prefix from being tracked.

This change ensures that the routing manager is aware of all non-ULA
on-link prefixes (even those with only the L flag set), which correctly
informs the decision to publish a default route.

This commit also:
- Updates `PrefixInfoOption` in `nd6.hpp` to use a `Flags` typedef and
  named constants instead of bitmasks.
- Updates `LogPrefixInfoOption` to log the state of L, A, and P flags.
- Adds a new unit test, `TestNonUlaPioWithOnlyOnLinkFlag`, to verify
  the new behavior.
This commit is contained in:
Abtin Keshavarzian
2025-09-17 16:06:29 -07:00
committed by GitHub
parent d27527ce54
commit fbc123940e
5 changed files with 229 additions and 72 deletions
+61 -46
View File
@@ -687,22 +687,6 @@ bool RoutingManager::IsValidOmrPrefix(const Ip6::Prefix &aPrefix)
return (aPrefix.GetLength() == kOmrPrefixLength) && !aPrefix.IsLinkLocal() && !aPrefix.IsMulticast();
}
bool RoutingManager::IsValidOnLinkPrefix(const PrefixInfoOption &aPio)
{
Ip6::Prefix prefix;
aPio.GetPrefix(prefix);
return IsValidOnLinkPrefix(prefix) && aPio.IsOnLinkFlagSet() &&
(aPio.IsAutoAddrConfigFlagSet() || aPio.IsDhcp6PdPreferredFlagSet());
}
bool RoutingManager::IsValidOnLinkPrefix(const Ip6::Prefix &aOnLinkPrefix)
{
return (aOnLinkPrefix.GetLength() == kOnLinkPrefixLength) && !aOnLinkPrefix.IsLinkLocal() &&
!aOnLinkPrefix.IsMulticast();
}
void RoutingManager::HandleRsSenderFinished(TimeMilli aStartTime)
{
// This is a callback from `RsSender` and is invoked when it
@@ -889,12 +873,15 @@ void RoutingManager::LogRaHeader(const RouterAdvert::Header &aRaHeader)
LogInfo("- RA Header - default route - lifetime:%u", aRaHeader.GetRouterLifetime());
}
void RoutingManager::LogPrefixInfoOption(const Ip6::Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime)
void RoutingManager::LogPrefixInfoOption(const Ip6::Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime,
PrefixInfoOption::Flags aFlags)
{
LogInfo("- PIO %s (valid:%lu, preferred:%lu)", aPrefix.ToString().AsCString(), ToUlong(aValidLifetime),
ToUlong(aPreferredLifetime));
LogInfo("- PIO %s (valid:%lu, preferred:%lu, flags - L:%u A:%u P:%u)", aPrefix.ToString().AsCString(),
ToUlong(aValidLifetime), ToUlong(aPreferredLifetime), (aFlags & PrefixInfoOption::kOnLinkFlag) ? 1 : 0,
(aFlags & PrefixInfoOption::kAutoConfigFlag) ? 1 : 0,
(aFlags & PrefixInfoOption::kDhcp6PdPreferredFlag) ? 1 : 0);
}
void RoutingManager::LogRouteInfoOption(const Ip6::Prefix &aPrefix, uint32_t aLifetime, RoutePreference aPreference)
@@ -930,7 +917,7 @@ const char *RoutingManager::RouterAdvOriginToString(RouterAdvOrigin aRaOrigin)
#else
void RoutingManager::LogRaHeader(const RouterAdvert::Header &) {}
void RoutingManager::LogPrefixInfoOption(const Ip6::Prefix &, uint32_t, uint32_t) {}
void RoutingManager::LogPrefixInfoOption(const Ip6::Prefix &, uint32_t, uint32_t, PrefixInfoOption::Flags) {}
void RoutingManager::LogRouteInfoOption(const Ip6::Prefix &, uint32_t, RoutePreference) {}
void RoutingManager::LogRecursiveDnsServerOption(const Ip6::Address &, uint32_t) {}
@@ -953,9 +940,11 @@ TimeMilli RoutingManager::LifetimedPrefix::CalculateExpirationTime(uint32_t aLif
void RoutingManager::OnLinkPrefix::SetFrom(const PrefixInfoOption &aPio)
{
aPio.GetPrefix(mPrefix);
mValidLifetime = aPio.GetValidLifetime();
mPreferredLifetime = aPio.GetPreferredLifetime();
mLastUpdateTime = TimerMilli::GetNow();
mValidLifetime = aPio.GetValidLifetime();
mPreferredLifetime = aPio.GetPreferredLifetime();
mAutoAddrConfigFlag = aPio.IsAutoAddrConfigFlagSet();
mDhcp6PdPreferredFlag = aPio.IsDhcp6PdPreferredFlagSet();
mLastUpdateTime = TimerMilli::GetNow();
}
void RoutingManager::OnLinkPrefix::SetFrom(const PrefixTableEntry &aPrefixTableEntry)
@@ -978,7 +967,7 @@ TimeMilli RoutingManager::OnLinkPrefix::GetStaleTime(void) const
return CalculateExpirationTime(Min(kStaleTime, mPreferredLifetime));
}
void RoutingManager::OnLinkPrefix::AdoptValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix)
void RoutingManager::OnLinkPrefix::AdoptFlagsAndValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix)
{
constexpr uint32_t kTwoHoursInSeconds = 2 * 3600;
@@ -1002,8 +991,10 @@ void RoutingManager::OnLinkPrefix::AdoptValidAndPreferredLifetimesFrom(const OnL
mValidLifetime = kTwoHoursInSeconds;
}
mPreferredLifetime = aPrefix.GetPreferredLifetime();
mLastUpdateTime = aPrefix.GetLastUpdateTime();
mPreferredLifetime = aPrefix.GetPreferredLifetime();
mAutoAddrConfigFlag = aPrefix.mAutoAddrConfigFlag;
mDhcp6PdPreferredFlag = aPrefix.mDhcp6PdPreferredFlag;
mLastUpdateTime = aPrefix.GetLastUpdateTime();
}
void RoutingManager::OnLinkPrefix::CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const
@@ -1019,10 +1010,15 @@ bool RoutingManager::OnLinkPrefix::IsFavoredOver(const Ip6::Prefix &aPrefix) con
{
bool isFavored = false;
// Validate that the `OnLinkPrefix` is eligible to be considered a
// favored on-link prefix. It must not be deprecated and have a
// preferred lifetime exceeding a minimum (1800 seconds).
// Validate that the `OnLinkPrefix` is eligible to be a favored
// on-link prefix. It must have a valid length and either the
// AutoAddrConfig (`A`) or Dhcp6PdPreferred (`P`) flag.
// Additionally, it must not be deprecated and its preferred
// lifetime must be at least `kFavoredMinPreferredLifetime`
// (1800) seconds.
VerifyOrExit(mPrefix.GetLength() == kOnLinkPrefixLength);
VerifyOrExit(mAutoAddrConfigFlag || mDhcp6PdPreferredFlag);
VerifyOrExit(!IsDeprecated());
VerifyOrExit(GetPreferredLifetime() >= kFavoredMinPreferredLifetime);
@@ -1468,12 +1464,24 @@ void RoutingManager::RxRaTracker::ProcessPrefixInfoOption(const PrefixInfoOption
Entry<OnLinkPrefix> *entry;
bool disregard;
// We track all valid PIO prefixes with the on-link (`L`) flag. The
// `OnLinkPrefix` entries store other PIO flags and are used by
// `DecisionFactors` to determine if a ULA or non-ULA on-link
// prefix has been observed. This decision then guides
// `RoutePublisher` on which route to publish. For determining the
// favored on-link prefix, only eligible `OnLinkPrefix` entries are
// considered. These entries must meet specific conditions, such as
// having a valid 64-bit length and either the AutoAddrConfig
// (`A`) and/or Dhcp6PdPreferred (`P`) flag set. The full set of
// conditions is covered in `OnLinkPrefix::IsFavoredOver()`.
VerifyOrExit(aPio.IsValid());
aPio.GetPrefix(prefix);
VerifyOrExit(!prefix.IsLinkLocal() && !prefix.IsMulticast());
if (!IsValidOnLinkPrefix(aPio))
if (!aPio.IsOnLinkFlagSet())
{
LogInfo("- PIO %s - ignore since not a valid on-link prefix", prefix.ToString().AsCString());
aRouter.mOnLinkPrefixes.RemoveMatching(prefix);
ExitNow();
}
@@ -1487,7 +1495,7 @@ void RoutingManager::RxRaTracker::ProcessPrefixInfoOption(const PrefixInfoOption
VerifyOrExit(!disregard);
#endif
LogPrefixInfoOption(prefix, aPio.GetValidLifetime(), aPio.GetPreferredLifetime());
LogPrefixInfoOption(prefix, aPio.GetValidLifetime(), aPio.GetPreferredLifetime(), aPio.GetFlags());
entry = aRouter.mOnLinkPrefixes.FindMatching(prefix);
@@ -1511,7 +1519,7 @@ void RoutingManager::RxRaTracker::ProcessPrefixInfoOption(const PrefixInfoOption
OnLinkPrefix newPrefix;
newPrefix.SetFrom(aPio);
entry->AdoptValidAndPreferredLifetimesFrom(newPrefix);
entry->AdoptFlagsAndValidAndPreferredLifetimesFrom(newPrefix);
}
entry->SetDisregardFlag(disregard);
@@ -3500,10 +3508,11 @@ Error RoutingManager::OnLinkPrefixManager::AppendCurPrefix(RouterAdvert::TxMessa
// If in `kDeprecating` state, we include it as PIO with zero
// preferred lifetime and the remaining valid lifetime.
Error error = kErrorNone;
uint32_t validLifetime = kDefaultOnLinkPrefixLifetime;
uint32_t preferredLifetime = kDefaultOnLinkPrefixLifetime;
TimeMilli now = TimerMilli::GetNow();
Error error = kErrorNone;
uint32_t validLifetime = kDefaultOnLinkPrefixLifetime;
uint32_t preferredLifetime = kDefaultOnLinkPrefixLifetime;
TimeMilli now = TimerMilli::GetNow();
PrefixInfoOption::Flags flags;
switch (GetState())
{
@@ -3522,9 +3531,11 @@ Error RoutingManager::OnLinkPrefixManager::AppendCurPrefix(RouterAdvert::TxMessa
ExitNow();
}
SuccessOrExit(error = aRaMessage.AppendPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime));
flags = PrefixInfoOption::kOnLinkFlag | PrefixInfoOption::kAutoConfigFlag;
LogPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime);
SuccessOrExit(error = aRaMessage.AppendPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime, flags));
LogPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime, flags);
exit:
return error;
@@ -3532,9 +3543,10 @@ exit:
Error RoutingManager::OnLinkPrefixManager::AppendOldPrefixes(RouterAdvert::TxMessage &aRaMessage)
{
Error error = kErrorNone;
TimeMilli now = TimerMilli::GetNow();
uint32_t validLifetime;
Error error = kErrorNone;
TimeMilli now = TimerMilli::GetNow();
uint32_t validLifetime;
PrefixInfoOption::Flags flags;
for (const OldPrefix &oldPrefix : mOldLocalPrefixes)
{
@@ -3544,9 +3556,12 @@ Error RoutingManager::OnLinkPrefixManager::AppendOldPrefixes(RouterAdvert::TxMes
}
validLifetime = TimeMilli::MsecToSec(oldPrefix.mExpireTime - now);
SuccessOrExit(error = aRaMessage.AppendPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0));
LogPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0);
flags = PrefixInfoOption::kOnLinkFlag | PrefixInfoOption::kAutoConfigFlag;
SuccessOrExit(error = aRaMessage.AppendPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0, flags));
LogPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0, flags);
}
exit:
+7 -4
View File
@@ -875,7 +875,7 @@ private:
bool IsDeprecated(void) const;
TimeMilli GetDeprecationTime(void) const;
TimeMilli GetStaleTime(void) const;
void AdoptValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix);
void AdoptFlagsAndValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix);
void CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const;
bool IsFavoredOver(const Ip6::Prefix &aPrefix) const;
@@ -883,6 +883,8 @@ private:
static constexpr uint32_t kFavoredMinPreferredLifetime = 1800; // In sec.
uint32_t mPreferredLifetime;
bool mAutoAddrConfigFlag : 1;
bool mDhcp6PdPreferredFlag : 1;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1870,11 +1872,12 @@ private:
static TimeMilli CalculateExpirationTime(TimeMilli aUpdateTime, uint32_t aLifetime);
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
static bool IsValidOnLinkPrefix(const PrefixInfoOption &aPio);
static bool IsValidOnLinkPrefix(const Ip6::Prefix &aOnLinkPrefix);
static void LogRaHeader(const RouterAdvert::Header &aRaHeader);
static void LogPrefixInfoOption(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
static void LogPrefixInfoOption(const Ip6::Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime,
PrefixInfoOption::Flags aFlags);
static void LogRouteInfoOption(const Ip6::Prefix &aPrefix, uint32_t aLifetime, RoutePreference aPreference);
static void LogRecursiveDnsServerOption(const Ip6::Address &aAddress, uint32_t aLifetime);
+5 -5
View File
@@ -292,9 +292,10 @@ exit:
//----------------------------------------------------------------------------------------------------------------------
// RouterAdver::TxMessage
Error RouterAdvert::TxMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime)
Error RouterAdvert::TxMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime,
PrefixInfoOption::Flags aFlags)
{
Error error = kErrorNone;
PrefixInfoOption *pio;
@@ -303,8 +304,7 @@ Error RouterAdvert::TxMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
VerifyOrExit(pio != nullptr, error = kErrorNoBufs);
pio->Init();
pio->SetOnLinkFlag();
pio->SetAutoAddrConfigFlag();
pio->SetFlags(aFlags);
pio->SetValidLifetime(aValidLifetime);
pio->SetPreferredLifetime(aPreferredLifetime);
pio->SetPrefix(aPrefix);
+32 -15
View File
@@ -178,28 +178,48 @@ class PrefixInfoOption : public Option, private Clearable<PrefixInfoOption>
public:
static constexpr Type kType = kTypePrefixInfo; ///< Prefix Information Option Type.
static constexpr uint8_t kOnLinkFlag = 0x80; ///< On-link - L flag.
static constexpr uint8_t kAutoConfigFlag = 0x40; ///< Autonomous address-configuration - A flag.
static constexpr uint8_t kDhcp6PdPreferredFlag = 0x10; ///< DHCPv6-PD preferred - P flag.
typedef uint8_t Flags; ///< Represents the flags as a bitmap.
/**
* Initializes the Prefix Info option with proper type and length and sets all other fields to zero.
*/
void Init(void);
/**
* Gets the raw flag bitmap.
*
* @return The flags bitmap.
*/
Flags GetFlags(void) const { return mFlags; }
/**
* Sets the raw flag bitmap.
*
* @param[in] aFlags The flags bitmap.
*/
void SetFlags(Flags aFlags) { mFlags = aFlags; }
/**
* Indicates whether or not the on-link flag is set.
*
* @retval TRUE The on-link flag is set.
* @retval FALSE The on-link flag is not set.
*/
bool IsOnLinkFlagSet(void) const { return (mFlags & kOnLinkFlagMask) != 0; }
bool IsOnLinkFlagSet(void) const { return (mFlags & kOnLinkFlag) != 0; }
/**
* Sets the on-link (L) flag.
*/
void SetOnLinkFlag(void) { mFlags |= kOnLinkFlagMask; }
void SetOnLinkFlag(void) { mFlags |= kOnLinkFlag; }
/**
* Clears the on-link (L) flag.
*/
void ClearOnLinkFlag(void) { mFlags &= ~kOnLinkFlagMask; }
void ClearOnLinkFlag(void) { mFlags &= ~kOnLinkFlag; }
/**
* Indicates whether or not the autonomous address-configuration (A) flag is set.
@@ -207,17 +227,17 @@ public:
* @retval TRUE The auto address-config flag is set.
* @retval FALSE The auto address-config flag is not set.
*/
bool IsAutoAddrConfigFlagSet(void) const { return (mFlags & kAutoConfigFlagMask) != 0; }
bool IsAutoAddrConfigFlagSet(void) const { return (mFlags & kAutoConfigFlag) != 0; }
/**
* Sets the autonomous address-configuration (A) flag.
*/
void SetAutoAddrConfigFlag(void) { mFlags |= kAutoConfigFlagMask; }
void SetAutoAddrConfigFlag(void) { mFlags |= kAutoConfigFlag; }
/**
* Clears the autonomous address-configuration (A) flag.
*/
void ClearAutoAddrConfigFlag(void) { mFlags &= ~kAutoConfigFlagMask; }
void ClearAutoAddrConfigFlag(void) { mFlags &= ~kAutoConfigFlag; }
/**
* Indicates whether or not the DhCPv6-PD Preferred (P) flag is set.
@@ -225,7 +245,7 @@ public:
* @retval TRUE The DHCPv6-PD Preferred (P) flag is set.
* @retval FALSE The DHCPv6-PD Preferred (P) flag is not set.
*/
bool IsDhcp6PdPreferredFlagSet(void) const { return (mFlags & kDhcp6PdPreferredFlagMask) != 0; }
bool IsDhcp6PdPreferredFlagSet(void) const { return (mFlags & kDhcp6PdPreferredFlag) != 0; }
/**
* Sets the valid lifetime of the prefix in seconds.
@@ -308,10 +328,6 @@ private:
// Reference for P Flag (DHCPv6-PD preferred flag):
// https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-6man-pio-pflag.xml
static constexpr uint8_t kOnLinkFlagMask = 0x80; // On-link - L flag.
static constexpr uint8_t kAutoConfigFlagMask = 0x40; // Autonomous address-configuration - A flag.
static constexpr uint8_t kDhcp6PdPreferredFlagMask = 0x10; // DHCPv6-PD preferred - P flag.
uint8_t mPrefixLength; // The prefix length in bits.
uint8_t mFlags; // The flags field.
uint32_t mValidLifetime; // The valid lifetime of the prefix.
@@ -898,17 +914,18 @@ public:
/**
* Appends a Prefix Info Option to the RA message.
*
* The appended Prefix Info Option will have both on-link (L) and autonomous address-configuration (A) flags
* set.
*
* @param[in] aPrefix The prefix.
* @param[in] aValidLifetime The valid lifetime in seconds.
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
* @param[in] aFlags The PIO flags to use.
*
* @retval kErrorNone Option is appended successfully.
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
*/
Error AppendPrefixInfoOption(const Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
Error AppendPrefixInfoOption(const Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime,
PrefixInfoOption::Flags aFlags);
/**
* Appends a Route Info Option to the RA message.
+124 -2
View File
@@ -816,16 +816,27 @@ void VerifyNat64PrefixInNetData(const Ip6::Prefix &aNat64Prefix)
struct Pio
{
Pio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime)
using Flags = Ip6::Nd::PrefixInfoOption::Flags;
static constexpr Flags kOnLinkFlag = Ip6::Nd::PrefixInfoOption::kOnLinkFlag;
static constexpr Flags kAutoConfigFlag = Ip6::Nd::PrefixInfoOption::kAutoConfigFlag;
static constexpr Flags kDhcp6Flag = Ip6::Nd::PrefixInfoOption::kDhcp6PdPreferredFlag;
Pio(const Ip6::Prefix &aPrefix,
uint32_t aValidLifetime,
uint32_t aPreferredLifetime,
Flags aFlags = kOnLinkFlag | kAutoConfigFlag)
: mPrefix(aPrefix)
, mValidLifetime(aValidLifetime)
, mPreferredLifetime(aPreferredLifetime)
, mFlags(aFlags)
{
}
const Ip6::Prefix &mPrefix;
uint32_t mValidLifetime;
uint32_t mPreferredLifetime;
Flags mFlags;
};
struct Rio
@@ -921,7 +932,8 @@ void BuildRouterAdvert(Ip6::Nd::RouterAdvert::TxMessage &aRaMsg,
for (; aNumPios > 0; aPios++, aNumPios--)
{
SuccessOrQuit(aRaMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime));
SuccessOrQuit(aRaMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime,
aPios->mFlags));
}
for (; aNumRios > 0; aRios++, aNumRios--)
@@ -2050,6 +2062,115 @@ void TestDefaultRoute(void)
FinalizeTest();
}
void TestNonUlaPioWithOnlyOnLinkFlag(void)
{
static constexpr uint32_t kMaxRaTxInterval = 196; // In seconds
Ip6::Prefix localOnLink;
Ip6::Prefix localOmr;
Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
uint16_t heapAllocations;
Log("--------------------------------------------------------------------------------------------");
Log("TestNonUlaPioWithOnlyOnLinkFlag");
InitTest();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Start Routing Manager. Check emitted RS and RA messages.
sRsEmitted = false;
sRaValidated = false;
sExpectedPio = kPioAdvertisingLocalOnLink;
sExpectedRios.Clear();
heapAllocations = sHeapAllocatedPtrs.GetLength();
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
sExpectedRios.Add(localOmr);
AdvanceTime(30000);
VerifyOrQuit(sRsEmitted);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sExpectedRios.SawAll());
Log("Received RA was validated");
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check the Network Data to include the local OMR and on-link prefix.
VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A with a new on-link (PIO) with
// only on-link (L) flag (no A or P).
SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime, Pio::kOnLinkFlag)});
sRaValidated = false;
AdvanceTime(10000);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check the discovered prefix table and ensure info from router A
// is present in the table.
VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check the Network Data. Now that we have observed a non-ULA
// on-link prefix (even with only on-link `L` flag), a default
// route should be published.
VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ true);
VerifyExternalRouteInNetData(kDefaultRoute, kWithAdvPioFlagSet);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that BR is still advertising its local on-link prefix.
AdvanceTime(kMaxRaTxInterval * 1000);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sExpectedRios.SawAll());
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Disallow responding to NS messages. This should cause
// the router A to be deemed unreachable and its prefix
// entries aged out and then removed.
sRespondToNs = false;
AdvanceTime(kValidLitime * 1000 + 1000);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the discovered prefix table is now empty.
VerifyPrefixTableIsEmpty();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Validate that the BR is no longer publishing a default route.
VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false);
VerifyExternalRouteInNetData(kUlaRoute, kWithAdvPioFlagSet);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
Log("End of TestNonUlaPioWithOnlyOnLinkFlag");
FinalizeTest();
}
void TestAdvNonUlaRoute(void)
{
Ip6::Prefix localOnLink;
@@ -5001,6 +5122,7 @@ int main(void)
ot::TestOmrSelection();
ot::TestOmrConfig();
ot::TestDefaultRoute();
ot::TestNonUlaPioWithOnlyOnLinkFlag();
ot::TestAdvNonUlaRoute();
ot::TestFavoredOnLinkPrefix();
ot::TestLocalOnLinkPrefixDeprecation();