mirror of
https://github.com/espressif/openthread.git
synced 2026-09-12 04:00:10 +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:
@@ -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