diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index d7d11c790..bb0e9d826 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -79,7 +79,7 @@ jobs: sudo rm /etc/apt/sources.list.d/* && sudo apt-get update sudo apt-get --no-install-recommends install -y ninja-build lcov - name: Build Simulation - run: ./script/cmake-build simulation -DOT_BUILD_GTEST=ON -DOT_BORDER_ROUTING=ON -DOT_NCP_INFRA_IF=ON + run: ./script/cmake-build simulation -DOT_BUILD_GTEST=ON -DOT_BORDER_ROUTING=ON -DOT_BORDER_ROUTING_DHCP6_PD=ON -DOT_NCP_INFRA_IF=ON - name: Test Simulation run: cd build/simulation && ninja test - name: Build Multipan Simulation diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index df7a9beab..3f4d065df 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -4068,7 +4068,7 @@ void RoutingManager::PdPrefixManager::Process(const RouterAdvert::Icmp6Packet *a Get().ScheduleRoutingPolicyEvaluation(kImmediately); } - if (HasPrefix() && currentPrefixUpdated) + if (HasPrefix()) { mTimer.FireAt(mPrefix.GetDeprecationTime()); } diff --git a/tests/unit/test_routing_manager.cpp b/tests/unit/test_routing_manager.cpp index 4e65383f5..44fa71115 100644 --- a/tests/unit/test_routing_manager.cpp +++ b/tests/unit/test_routing_manager.cpp @@ -4287,6 +4287,57 @@ void TestBorderRoutingProcessPlatfromGeneratedNd(void) VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false); } + // 6. Replace a prefix, on some platforms, there might be no messages to deprecate the old prefix, instead, they + // send new prefixes directly. + // In this case, we still use the old prefix as long as the old prefix preferred lifetime is not exceeded, and + // replace it with the new prefix when expired. + Log("6. Replace prefix."); + { + Ip6::Prefix raPrefix = PrefixFromString("2001:db8:1:2::", 64); + Ip6::Prefix newRaPrefix = PrefixFromString("2001:db8:3:4::", 64); + + SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(raPrefix, kValidLitime, kPreferredLifetime)}); + + sExpectedRios.Add(raPrefix); + sExpectedRios.Clear(); + AdvanceTime(10 * 1000); + + VerifyPdOmrPrefix(raPrefix); + VerifyOmrPrefixInNetData(raPrefix, /* aDefaultRoute */ false); + + AdvanceTime(1000 * 1000); + VerifyPdOmrPrefix(raPrefix); + + // Send new prefix without deprecating old prefix. + // The old prefix should be preferred for another (1800 - 10 - 1000) = 790s + SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(newRaPrefix, kValidLitime, kPreferredLifetime)}); + AdvanceTime(500 * 1000); + VerifyPdOmrPrefix(raPrefix); + + AdvanceTime(300 * 1000); + // Old Prefix should be removed now. + VerifyNoPdOmrPrefix(); + + sExpectedRios.Add(newRaPrefix); + + // When the prefix is replaced, there will be a short period when the old prefix is still in the netdata, and PD + // manager will refuse to request the prefix. + SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(newRaPrefix, kValidLitime, kPreferredLifetime)}); + // Advance a short period of time to wait for a stable PD state. + AdvanceTime(5000); + VerifyOrQuit(sInstance->Get().GetDhcp6PdState() == + BorderRouter::RoutingManager::kDhcp6PdStateRunning); + SendRouterAdvertToBorderRoutingProcessIcmp6Ra({Pio(newRaPrefix, kValidLitime, kPreferredLifetime)}); + + AdvanceTime(1000 * 1000); + VerifyOrQuit(sExpectedRios.SawAll()); + VerifyPdOmrPrefix(newRaPrefix); + + AdvanceTime(1000 * 1000); + VerifyNoPdOmrPrefix(); + VerifyOmrPrefixInNetData(localOmr, /* aDefaultRoute */ false); + } + SuccessOrQuit(otBorderRoutingSetEnabled(sInstance, false)); VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);