mirror of
https://github.com/espressif/openthread.git
synced 2026-08-10 04:37:47 +00:00
[routing-manager] employ RA hash tracking to detect self-originating RAs (#9939)
This commit updates how `RoutingManager` differentiates between self-generated RA messages and those from other sources sending RA on the same device. This enables learning of the RA header, specifically the default route lifetime. This commit introduces a new mechanism to calculate and store a SHA256 hash of recently emitted RAs. Received RAs are cross-referenced against the stored hashes to determine their origin. This replaces the prior method, which relied on parsing and analyzing the included options in the received RA. A new test case is added in `test_routing_manager` to validate the learning of RA header from other sources on same device.
This commit is contained in:
@@ -160,6 +160,12 @@ bool sRespondToNs; // Indicates whether or not to respond to NS.
|
||||
ExpectedPio sExpectedPio; // Expected PIO in the emitted RA by BR (MUST be seen in RA to set `sRaValidated`).
|
||||
uint32_t sOnLinkLifetime; // Valid lifetime for local on-link prefix from the last processed RA.
|
||||
|
||||
// Indicate whether or not to check the emitted RA header (default route) lifetime
|
||||
bool sCheckRaHeaderLifetime;
|
||||
|
||||
// Expected default route lifetime in emitted RA header by BR.
|
||||
uint32_t sExpectedRaHeaderLifetime;
|
||||
|
||||
enum ExpectedRaHeaderFlags
|
||||
{
|
||||
kRaHeaderFlagsSkipChecking, // Skip checking the RA header flags.
|
||||
@@ -424,7 +430,10 @@ void ValidateRouterAdvert(const Icmp6Packet &aPacket)
|
||||
|
||||
VerifyOrQuit(raMsg.IsValid());
|
||||
|
||||
VerifyOrQuit(raMsg.GetHeader().GetRouterLifetime() == 0);
|
||||
if (sCheckRaHeaderLifetime)
|
||||
{
|
||||
VerifyOrQuit(raMsg.GetHeader().GetRouterLifetime() == sExpectedRaHeaderLifetime);
|
||||
}
|
||||
|
||||
switch (sExpectedRaHeaderFlags)
|
||||
{
|
||||
@@ -1188,8 +1197,10 @@ void InitTest(bool aEnablBorderRouting = false, bool aAfterReset = false)
|
||||
sRaValidated = false;
|
||||
sExpectedPio = kNoPio;
|
||||
sExpectedRios.Clear();
|
||||
sRespondToNs = true;
|
||||
sExpectedRaHeaderFlags = kRaHeaderFlagsNone;
|
||||
sRespondToNs = true;
|
||||
sExpectedRaHeaderFlags = kRaHeaderFlagsNone;
|
||||
sCheckRaHeaderLifetime = true;
|
||||
sExpectedRaHeaderLifetime = 0;
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Ensure device starts as leader.
|
||||
@@ -2950,6 +2961,93 @@ void TestLearningAndCopyingOfFlags(void)
|
||||
FinalizeTest();
|
||||
}
|
||||
|
||||
void TestLearnRaHeader(void)
|
||||
{
|
||||
Ip6::Prefix localOnLink;
|
||||
Ip6::Prefix localOmr;
|
||||
Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
|
||||
uint16_t heapAllocations;
|
||||
|
||||
Log("--------------------------------------------------------------------------------------------");
|
||||
Log("TestLearnRaHeader");
|
||||
|
||||
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");
|
||||
|
||||
VerifyDiscoveredRoutersIsEmpty();
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Send an RA from the same address (another entity on the device)
|
||||
// advertising a default route.
|
||||
|
||||
SendRouterAdvert(sInfraIfAddress, DefaultRoute(1000, NetworkData::kRoutePreferenceLow));
|
||||
|
||||
AdvanceTime(1);
|
||||
VerifyDiscoveredRouters({InfraRouter(sInfraIfAddress, /* M */ false, /* O */ false, /* StubRouter */ false)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// RoutingManager should learn the header from the
|
||||
// received RA (from same address) and start advertising
|
||||
// the same default route lifetime in the emitted RAs.
|
||||
|
||||
sRaValidated = false;
|
||||
sCheckRaHeaderLifetime = true;
|
||||
sExpectedRaHeaderLifetime = 1000;
|
||||
|
||||
AdvanceTime(30 * 1000);
|
||||
VerifyOrQuit(sRaValidated);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Wait for longer than entry lifetime (for it to expire) and
|
||||
// make sure `RoutingManager` stops advertising default route.
|
||||
|
||||
sCheckRaHeaderLifetime = false;
|
||||
|
||||
AdvanceTime(1000 * 1000);
|
||||
|
||||
sRaValidated = false;
|
||||
sCheckRaHeaderLifetime = true;
|
||||
sExpectedRaHeaderLifetime = 0;
|
||||
|
||||
AdvanceTime(700 * 1000);
|
||||
VerifyOrQuit(sRaValidated);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(false));
|
||||
VerifyDiscoveredRoutersIsEmpty();
|
||||
|
||||
VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
|
||||
|
||||
Log("End of TestLearnRaHeader");
|
||||
FinalizeTest();
|
||||
}
|
||||
|
||||
void TestConflictingPrefix(void)
|
||||
{
|
||||
static const otExtendedPanId kExtPanId1 = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x08}};
|
||||
@@ -3921,6 +4019,7 @@ int main(void)
|
||||
ot::TestConflictingPrefix();
|
||||
ot::TestRouterNsProbe();
|
||||
ot::TestLearningAndCopyingOfFlags();
|
||||
ot::TestLearnRaHeader();
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
|
||||
ot::TestSavedOnLinkPrefixes();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user