mirror of
https://github.com/espressif/openthread.git
synced 2026-08-17 16:09:51 +00:00
[dhcp6-pd] stop PrefixManager when RoutingManager is stopped (#9608)
When InfraIf is down and we received a RA from the host interface, we may trigger the EvaluateRoutingPolicy unexpectly. This might happen when infra if and uplink are separate interfaces. This commit fixes this by adding Start and Stop to `PdPrefixManager` to start / stop handling RA messages.
This commit is contained in:
@@ -342,6 +342,9 @@ void RoutingManager::Start(void)
|
||||
mOmrPrefixManager.Start();
|
||||
mRoutePublisher.Start();
|
||||
mRsSender.Start();
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
mPdPrefixManager.Start();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
|
||||
mNat64PrefixManager.Start();
|
||||
#endif
|
||||
@@ -354,7 +357,9 @@ void RoutingManager::Stop(void)
|
||||
|
||||
mOmrPrefixManager.Stop();
|
||||
mOnLinkPrefixManager.Stop();
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
mPdPrefixManager.Stop();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
|
||||
mNat64PrefixManager.Stop();
|
||||
#endif
|
||||
@@ -3429,14 +3434,76 @@ exit:
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
const char *RoutingManager::PdPrefixManager::StateToString(Dhcp6PdState aState)
|
||||
{
|
||||
static const char *const kStateStrings[] = {
|
||||
"Disabled", // (0) kDisabled
|
||||
"Stopped", // (1) kStopped
|
||||
"Running", // (2) kRunning
|
||||
};
|
||||
|
||||
static_assert(0 == kDhcp6PdStateDisabled, "kDhcp6PdStateDisabled value is incorrect");
|
||||
static_assert(1 == kDhcp6PdStateStopped, "kDhcp6PdStateStopped value is incorrect");
|
||||
static_assert(2 == kDhcp6PdStateRunning, "kDhcp6PdStateRunning value is incorrect");
|
||||
|
||||
return kStateStrings[aState];
|
||||
}
|
||||
|
||||
RoutingManager::PdPrefixManager::PdPrefixManager(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mEnabled(false)
|
||||
, mIsRunning(false)
|
||||
, mTimer(aInstance)
|
||||
{
|
||||
mPrefix.Clear();
|
||||
}
|
||||
|
||||
void RoutingManager::PdPrefixManager::StartStop(bool aStart)
|
||||
{
|
||||
Dhcp6PdState oldState = GetState();
|
||||
|
||||
VerifyOrExit(aStart != mIsRunning);
|
||||
mIsRunning = aStart;
|
||||
EvaluateStateChange(oldState);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
RoutingManager::Dhcp6PdState RoutingManager::PdPrefixManager::GetState(void) const
|
||||
{
|
||||
Dhcp6PdState state = kDhcp6PdStateDisabled;
|
||||
|
||||
if (mEnabled)
|
||||
{
|
||||
state = mIsRunning ? kDhcp6PdStateRunning : kDhcp6PdStateStopped;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void RoutingManager::PdPrefixManager::EvaluateStateChange(Dhcp6PdState aOldState)
|
||||
{
|
||||
Dhcp6PdState newState = GetState();
|
||||
|
||||
VerifyOrExit(aOldState != newState);
|
||||
LogInfo("PdPrefixManager: %s -> %s", StateToString(aOldState), StateToString(newState));
|
||||
|
||||
// TODO: We may also want to inform the platform that PD is stopped.
|
||||
switch (newState)
|
||||
{
|
||||
case kDhcp6PdStateDisabled:
|
||||
case kDhcp6PdStateStopped:
|
||||
WithdrawPrefix();
|
||||
break;
|
||||
case kDhcp6PdStateRunning:
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Error RoutingManager::PdPrefixManager::GetPrefixInfo(PrefixTableEntry &aInfo) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
@@ -3472,7 +3539,7 @@ void RoutingManager::PdPrefixManager::ProcessPlatformGeneratedRa(const uint8_t *
|
||||
Error error = kErrorNone;
|
||||
Ip6::Nd::RouterAdvertMessage::Icmp6Packet packet;
|
||||
|
||||
VerifyOrExit(mEnabled, LogWarn("Ignore platform generated RA since PD is disabled."));
|
||||
VerifyOrExit(IsRunning(), LogWarn("Ignore platform generated RA since PD is disabled or not running."));
|
||||
packet.Init(aRouterAdvert, aLength);
|
||||
error = Process(Ip6::Nd::RouterAdvertMessage(packet));
|
||||
|
||||
@@ -3563,15 +3630,11 @@ exit:
|
||||
|
||||
void RoutingManager::PdPrefixManager::SetEnabled(bool aEnabled)
|
||||
{
|
||||
Dhcp6PdState oldState = GetState();
|
||||
|
||||
VerifyOrExit(mEnabled != aEnabled);
|
||||
|
||||
mEnabled = aEnabled;
|
||||
if (!aEnabled)
|
||||
{
|
||||
WithdrawPrefix();
|
||||
}
|
||||
|
||||
LogInfo("PdPrefixManager is %s", aEnabled ? "enabled" : "disabled");
|
||||
EvaluateStateChange(oldState);
|
||||
|
||||
exit:
|
||||
return;
|
||||
|
||||
@@ -121,9 +121,9 @@ public:
|
||||
*/
|
||||
enum Dhcp6PdState : uint8_t
|
||||
{
|
||||
kDhcp6PdStateDisabled = OT_BORDER_ROUTING_STATE_DISABLED, ///< Disabled.
|
||||
kDhcp6PdStateStopped = OT_BORDER_ROUTING_STATE_STOPPED, ///< Enabled, but currently stopped.
|
||||
kDhcp6PdStateRunning = OT_BORDER_ROUTING_STATE_RUNNING, ///< Enabled, and running.
|
||||
kDhcp6PdStateDisabled = OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED, ///< Disabled.
|
||||
kDhcp6PdStateStopped = OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED, ///< Enabled, but currently stopped.
|
||||
kDhcp6PdStateRunning = OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING, ///< Enabled, and running.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1169,20 +1169,19 @@ private:
|
||||
explicit PdPrefixManager(Instance &aInstance);
|
||||
|
||||
void SetEnabled(bool aEnabled);
|
||||
void Start(void) { StartStop(/* aStart= */ true); }
|
||||
void Stop(void) { StartStop(/* aStart= */ false); }
|
||||
bool IsRunning(void) const { return GetState() == Dhcp6PdState::kDhcp6PdStateRunning; }
|
||||
bool HasPrefix(void) const { return IsValidOmrPrefix(mPrefix.GetPrefix()); }
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix.GetPrefix(); }
|
||||
Dhcp6PdState GetState(void) const
|
||||
{
|
||||
// TODO: We need to stop and inform the platform when there is already a GUA prefix advertised in the
|
||||
// network.
|
||||
return mEnabled ? kDhcp6PdStateRunning : kDhcp6PdStateDisabled;
|
||||
}
|
||||
Dhcp6PdState GetState(void) const;
|
||||
|
||||
void ProcessPlatformGeneratedRa(const uint8_t *aRouterAdvert, uint16_t aLength);
|
||||
Error GetPrefixInfo(PrefixTableEntry &aInfo) const;
|
||||
void HandleTimer(void) { WithdrawPrefix(); }
|
||||
|
||||
static const char *StateToString(Dhcp6PdState aState);
|
||||
|
||||
static bool IsValidPdPrefix(const Ip6::Prefix &aPrefix)
|
||||
{
|
||||
// We should accept ULA prefix since it could be used by the internet infrastructure like NAT64.
|
||||
@@ -1192,11 +1191,14 @@ private:
|
||||
|
||||
private:
|
||||
Error Process(const Ip6::Nd::RouterAdvertMessage &aMessage);
|
||||
void EvaluateStateChange(Dhcp6PdState aOldState);
|
||||
void WithdrawPrefix(void);
|
||||
void StartStop(bool aStart);
|
||||
|
||||
using PlatformOmrPrefixTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandlePdPrefixManagerTimer>;
|
||||
|
||||
bool mEnabled;
|
||||
bool mIsRunning;
|
||||
PlatformOmrPrefixTimer mTimer;
|
||||
DiscoveredPrefixTable::Entry mPrefix;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user