[nat64] simplify state management (#11908)

This change simplifies the state management logic in the NAT64
translator by removing the `mEnabled` boolean flag. The `mState` enum
is now the single source of truth for the translator's operational
status.

A new `SetState()` method centralizes the actions performed when
transitioning to a new state, such as logging, signaling notifiers,
and clearing active mappings. The `IsEnabled()` helper is introduced
to check if the current state is not `kStateDisabled`.

Consequently, functions like `SetEnabled()` and `UpdateState()` are
updated to use the new `SetState()` function, making state
transitions more explicit and maintainable.
This commit is contained in:
Abtin Keshavarzian
2025-09-10 21:21:51 -07:00
committed by GitHub
parent 07a278fb29
commit ddbcaa6aee
2 changed files with 55 additions and 49 deletions
+51 -47
View File
@@ -65,8 +65,7 @@ const char *StateToString(State aState)
Translator::Translator(Instance &aInstance)
: InstanceLocator(aInstance)
, mEnabled(false)
, mState(State::kStateDisabled)
, mState(kStateDisabled)
, mMappingPool(aInstance)
, mTimer(aInstance)
{
@@ -630,11 +629,18 @@ exit:
void Translator::ClearIp4Cidr(void)
{
VerifyOrExit(mIp4Cidr.mLength != 0);
LogInfo("Clearing IPv4 CIDR");
mIp4Cidr.Clear();
mActiveMappings.Free();
mIp4AddressPool.Clear();
UpdateState();
exit:
return;
}
Error Translator::GetIp4Cidr(Ip4::Cidr &aCidr) const
@@ -650,29 +656,24 @@ exit:
void Translator::SetNat64Prefix(const Ip6::Prefix &aNat64Prefix)
{
if (aNat64Prefix.GetLength() == 0)
{
ClearNat64Prefix();
}
else if (mNat64Prefix != aNat64Prefix)
{
LogInfo("IPv6 Prefix for NAT64 updated to %s", aNat64Prefix.ToString().AsCString());
mNat64Prefix = aNat64Prefix;
UpdateState();
}
}
VerifyOrExit(mNat64Prefix != aNat64Prefix);
LogInfo("NAT64 Prefix: %s -> %s", mNat64Prefix.ToString().AsCString(), aNat64Prefix.ToString().AsCString());
void Translator::ClearNat64Prefix(void)
{
VerifyOrExit(mNat64Prefix.GetLength() != 0);
mNat64Prefix.Clear();
LogInfo("IPv6 Prefix for NAT64 cleared");
mNat64Prefix = aNat64Prefix;
UpdateState();
exit:
return;
}
void Translator::ClearNat64Prefix(void)
{
Ip6::Prefix prefix;
prefix.Clear();
SetNat64Prefix(prefix);
}
Error Translator::GetNat64Prefix(Ip6::Prefix &aPrefix) const
{
Error error = kErrorNone;
@@ -761,47 +762,50 @@ void Translator::ProtocolCounters::Update4To6(Counters &aCounters, uint16_t aSiz
aCounters.m4To6Bytes += aSize;
}
void Translator::UpdateState(void)
void Translator::SetState(State aState)
{
State newState;
VerifyOrExit(mState != aState);
if (mEnabled)
{
if (mIp4Cidr.mLength > 0 && mNat64Prefix.IsValidNat64())
{
newState = kStateActive;
}
else
{
newState = kStateNotRunning;
}
}
else
{
newState = kStateDisabled;
}
LogInfo("State: %s -> %s", StateToString(mState), StateToString(aState));
mState = aState;
SuccessOrExit(Get<Notifier>().Update(mState, newState, kEventNat64TranslatorStateChanged));
LogInfo("NAT64 translator is now %s", StateToString(mState));
Get<Notifier>().Signal(kEventNat64TranslatorStateChanged);
switch (mState)
{
case kStateDisabled:
case kStateNotRunning:
case kStateIdle:
mActiveMappings.Free();
break;
case kStateActive:
break;
}
exit:
return;
}
void Translator::SetEnabled(bool aEnabled)
bool Translator::HasValidPrefixAndCidr(void) const { return (mIp4Cidr.mLength > 0) && mNat64Prefix.IsValidNat64(); }
void Translator::UpdateState(void)
{
VerifyOrExit(mEnabled != aEnabled);
mEnabled = aEnabled;
if (!aEnabled)
if (IsEnabled())
{
mActiveMappings.Free();
SetState(HasValidPrefixAndCidr() ? kStateActive : kStateNotRunning);
}
}
UpdateState();
exit:
return;
void Translator::SetEnabled(bool aEnable)
{
if (aEnable)
{
SetState(HasValidPrefixAndCidr() ? kStateActive : kStateNotRunning);
}
else
{
SetState(kStateDisabled);
}
}
} // namespace Nat64
+4 -2
View File
@@ -337,11 +337,14 @@ private:
#endif
};
bool IsEnabled(void) const { return mState != kStateDisabled; }
bool HasValidPrefixAndCidr(void) const;
void SetState(State aState);
void UpdateState(void);
Error TranslateIcmp4(Message &aMessage, uint16_t aOriginalId);
Error TranslateIcmp6(Message &aMessage, uint16_t aTranslatedId);
Mapping *AllocateMapping(const Ip6::Headers &aIp6Headers);
void HandleTimer(void);
void UpdateState(void);
#if OPENTHREAD_CONFIG_NAT64_PORT_TRANSLATION_ENABLE
uint16_t AllocateSourcePort(uint16_t aSrcPort);
#endif
@@ -351,7 +354,6 @@ private:
using TranslatorTimer = TimerMilliIn<Translator, &Translator::HandleTimer>;
bool mEnabled;
State mState;
uint64_t mNextMappingId;
Array<Ip4::Address, kPoolSize> mIp4AddressPool;