mirror of
https://github.com/espressif/openthread.git
synced 2026-08-03 01:17:46 +00:00
[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:
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user