diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 352224bb3..c575f06f0 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (196) +#define OPENTHREAD_API_VERSION (197) /** * @addtogroup api-instance diff --git a/include/openthread/platform/settings.h b/include/openthread/platform/settings.h index 39e0613bb..b93a15d10 100644 --- a/include/openthread/platform/settings.h +++ b/include/openthread/platform/settings.h @@ -68,12 +68,13 @@ enum OT_SETTINGS_KEY_RESERVED = 0x0006, ///< Reserved (previously auto-start). OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY = 0x0007, ///< SLAAC key to generate semantically opaque IID. OT_SETTINGS_KEY_DAD_INFO = 0x0008, ///< Duplicate Address Detection (DAD) information. - OT_SETTINGS_KEY_OMR_PREFIX = 0x0009, ///< Off-mesh routable (OMR) prefix. + OT_SETTINGS_KEY_LEGACY_OMR_PREFIX = 0x0009, ///< Reserved. Legacy Off-mesh routable (OMR) prefix. OT_SETTINGS_KEY_ON_LINK_PREFIX = 0x000a, ///< On-link prefix for infrastructure link. OT_SETTINGS_KEY_SRP_ECDSA_KEY = 0x000b, ///< SRP client ECDSA public/private key pair. OT_SETTINGS_KEY_SRP_CLIENT_INFO = 0x000c, ///< The SRP client info (selected SRP server address). OT_SETTINGS_KEY_SRP_SERVER_INFO = 0x000d, ///< The SRP server info (UDP port). - OT_SETTINGS_KEY_NAT64_PREFIX = 0x000e, ///< NAT64 prefix. + OT_SETTINGS_KEY_LEGACY_NAT64_PREFIX = 0x000e, ///< Reserved. Legacy NAT64 prefix. + OT_SETTINGS_KEY_BR_ULA_PREFIX = 0x000f, ///< BR ULA prefix. }; /** diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 69d3287d7..eab130619 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -79,6 +79,8 @@ RoutingManager::RoutingManager(Instance &aInstance) , mRouterSolicitCount(0) , mRoutingPolicyTimer(aInstance, HandleRoutingPolicyTimer) { + mBrUlaPrefix.Clear(); + mLocalOmrPrefix.Clear(); mLocalOnLinkPrefix.Clear(); @@ -93,11 +95,12 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning) VerifyOrExit(!IsInitialized(), error = kErrorInvalidState); VerifyOrExit(aInfraIfIndex > 0, error = kErrorInvalidArgs); - SuccessOrExit(error = LoadOrGenerateRandomOmrPrefix()); - SuccessOrExit(error = LoadOrGenerateRandomOnLinkPrefix()); + SuccessOrExit(error = LoadOrGenerateRandomBrUlaPrefix()); + GenerateOmrPrefix(); #if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE - SuccessOrExit(error = LoadOrGenerateRandomNat64Prefix()); + GenerateNat64Prefix(); #endif + SuccessOrExit(error = LoadOrGenerateRandomOnLinkPrefix()); mInfraIfIndex = aInfraIfIndex; @@ -162,38 +165,62 @@ exit: } #endif -Error RoutingManager::LoadOrGenerateRandomOmrPrefix(void) +Error RoutingManager::LoadOrGenerateRandomBrUlaPrefix(void) { Error error = kErrorNone; bool generated = false; - if (Get().Read(mLocalOmrPrefix) != kErrorNone || !IsValidOmrPrefix(mLocalOmrPrefix)) + if (Get().Read(mBrUlaPrefix) != kErrorNone || !IsValidBrUlaPrefix(mBrUlaPrefix)) { - Ip6::NetworkPrefix randomOmrPrefix; + Ip6::NetworkPrefix randomUlaPrefix; - LogNote("No valid OMR prefix found in settings, generating new one"); + LogNote("No valid /48 BR ULA prefix found in settings, generating new one"); - // TODO: generate OMR prefix from the /48 BR ULA prefix - error = randomOmrPrefix.GenerateRandomUla(); - if (error != kErrorNone) - { - LogCrit("Failed to generate random OMR prefix"); - ExitNow(); - } + SuccessOrExit(error = randomUlaPrefix.GenerateRandomUla()); - mLocalOmrPrefix.Set(randomOmrPrefix); - IgnoreError(Get().Save(mLocalOmrPrefix)); + mBrUlaPrefix.Set(randomUlaPrefix); + mBrUlaPrefix.SetSubnetId(0); + mBrUlaPrefix.SetLength(kBrUlaPrefixLength); + + IgnoreError(Get().Save(mBrUlaPrefix)); generated = true; } OT_UNUSED_VARIABLE(generated); - LogNote("Local OMR prefix: %s (%s)", mLocalOmrPrefix.ToString().AsCString(), generated ? "generated" : "loaded"); + LogNote("BR ULA prefix: %s (%s)", mBrUlaPrefix.ToString().AsCString(), generated ? "generated" : "loaded"); exit: + if (error != kErrorNone) + { + LogCrit("Failed to generate random /48 BR ULA prefix"); + } return error; } +void RoutingManager::GenerateOmrPrefix(void) +{ + IgnoreError(Get().Delete()); + + mLocalOmrPrefix = mBrUlaPrefix; + mLocalOmrPrefix.SetSubnetId(kOmrPrefixSubnetId); + mLocalOmrPrefix.SetLength(kOmrPrefixLength); + + LogInfo("Generated OMR prefix: %s", mLocalOmrPrefix.ToString().AsCString()); +} + +#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE +void RoutingManager::GenerateNat64Prefix(void) +{ + mLocalNat64Prefix = mBrUlaPrefix; + mLocalNat64Prefix.SetSubnetId(kNat64PrefixSubnetId); + mLocalNat64Prefix.mPrefix.mFields.m32[2] = 0; + mLocalNat64Prefix.SetLength(kNat64PrefixLength); + + LogInfo("Generated NAT64 prefix: %s", mLocalNat64Prefix.ToString().AsCString()); +} +#endif + Error RoutingManager::LoadOrGenerateRandomOnLinkPrefix(void) { Error error = kErrorNone; @@ -211,9 +238,8 @@ Error RoutingManager::LoadOrGenerateRandomOnLinkPrefix(void) ExitNow(); } - randomOnLinkPrefix.m8[6] = 0; - randomOnLinkPrefix.m8[7] = 0; mLocalOnLinkPrefix.Set(randomOnLinkPrefix); + mLocalOnLinkPrefix.SetSubnetId(0); IgnoreError(Get().Save(mLocalOnLinkPrefix)); generated = true; @@ -228,39 +254,6 @@ exit: return error; } -#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE -Error RoutingManager::LoadOrGenerateRandomNat64Prefix(void) -{ - Error error = kErrorNone; - - if (Get().Read(mLocalNat64Prefix) != kErrorNone || - !mLocalNat64Prefix.IsValidNat64()) - { - Ip6::NetworkPrefix randomNat64Prefix; - constexpr uint8_t nat64PrefixLength = 96; - - LogNote("No valid NAT64 prefix found in settings, generating new one"); - - // TODO: generate NAT64 prefix from the /48 BR ULA prefix - error = randomNat64Prefix.GenerateRandomUla(); - if (error != kErrorNone) - { - LogCrit("Failed to generate random NAT64 prefix"); - ExitNow(); - } - - mLocalNat64Prefix.Clear(); - mLocalNat64Prefix.Set(randomNat64Prefix); - mLocalNat64Prefix.SetLength(nat64PrefixLength); - - IgnoreError(Get().Save(mLocalNat64Prefix)); - } - -exit: - return error; -} -#endif - void RoutingManager::EvaluateState(void) { if (mIsEnabled && Get().IsAttached() && mInfraIfIsRunning) @@ -945,6 +938,11 @@ void RoutingManager::SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefix } } +bool RoutingManager::IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix) +{ + return aBrUlaPrefix.mLength == kBrUlaPrefixLength && aBrUlaPrefix.mPrefix.mFields.m8[0] == 0xfd; +} + bool RoutingManager::IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig) { return IsValidOmrPrefix(aOnMeshPrefixConfig.GetPrefix()) && aOnMeshPrefixConfig.mSlaac && !aOnMeshPrefixConfig.mDp; diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index cd6e14bf9..ea9e454da 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -198,6 +198,11 @@ private: static constexpr uint8_t kOmrPrefixLength = OT_IP6_PREFIX_BITSIZE; // The length of an OMR prefix. In bits. static constexpr uint8_t kOnLinkPrefixLength = OT_IP6_PREFIX_BITSIZE; // The length of an On-link prefix. In bits. + static constexpr uint8_t kBrUlaPrefixLength = 48; // The length of a BR ULA prefix. In bits. + static constexpr uint8_t kNat64PrefixLength = 96; // The length of a NAT64 prefix. In bits. + + static constexpr uint16_t kOmrPrefixSubnetId = 1; // The subnet ID of an OMR prefix within a BR ULA prefix. + static constexpr uint16_t kNat64PrefixSubnetId = 2; // The subnet ID of a NAT64 prefix within a BR ULA prefix. // The maximum number of initial Router Advertisements. static constexpr uint32_t kMaxInitRtrAdvertisements = 3; @@ -289,14 +294,15 @@ private: void HandleNotifierEvents(Events aEvents); bool IsInitialized(void) const { return mInfraIfIndex != 0; } bool IsEnabled(void) const { return mIsEnabled; } - Error LoadOrGenerateRandomOmrPrefix(void); + Error LoadOrGenerateRandomBrUlaPrefix(void); + void GenerateOmrPrefix(void); Error LoadOrGenerateRandomOnLinkPrefix(void); const Ip6::Prefix *EvaluateOnLinkPrefix(void); #if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE - Error LoadOrGenerateRandomNat64Prefix(void); - void EvaluateNat64Prefix(void); + void GenerateNat64Prefix(void); + void EvaluateNat64Prefix(void); #endif void EvaluateRoutingPolicy(void); @@ -338,6 +344,7 @@ private: bool UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage *aRouterAdvMessage); void ResetDiscoveredPrefixStaleTimer(void); + static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix); static bool IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig); static bool IsValidOmrPrefix(const Ip6::Prefix &aOmrPrefix); static bool IsValidOnLinkPrefix(const RouterAdv::PrefixInfoOption &aPio); @@ -358,8 +365,11 @@ private: // messages will be sent. uint32_t mInfraIfIndex; - // The OMR prefix loaded from local persistent storage or randomly - // generated if non is found in persistent storage. + // The /48 BR ULA prefix loaded from local persistent storage or + // randomly generated if none is found in persistent storage. + Ip6::Prefix mBrUlaPrefix; + + // The OMR prefix allocated from the /48 BR ULA prefix. Ip6::Prefix mLocalOmrPrefix; // The advertised OMR prefixes. For a stable Thread network without @@ -381,8 +391,7 @@ private: TimeMilli mTimeAdvertisedOnLinkPrefix; TimerMilli mOnLinkPrefixDeprecateTimer; - // The NAT64 prefix loaded from local persistent storage or - // randomly generated if none is found in persistent storage. + // The NAT64 prefix allocated from the /48 BR ULA prefix. Ip6::Prefix mLocalNat64Prefix; // True if the local NAT64 prefix is advertised in Thread network. diff --git a/src/core/common/settings.cpp b/src/core/common/settings.cpp index c7702e15d..89b78f5a3 100644 --- a/src/core/common/settings.cpp +++ b/src/core/common/settings.cpp @@ -149,12 +149,13 @@ const char *SettingsBase::KeyToString(Key aKey) "", // (6) kKeyReserved "SlaacIidSecretKey", // (7) kKeySlaacIidSecretKey "DadInfo", // (8) kKeyDadInfo - "OmrPrefix", // (9) kKeyOmrPrefix + "LegacyOmrPrefix", // (9) kKeyLegacyOmrPrefix "OnLinkPrefix", // (10) kKeyOnLinkPrefix "SrpEcdsaKey", // (11) kKeySrpEcdsaKey "SrpClientInfo", // (12) kKeySrpClientInfo "SrpServerInfo", // (13) kKeySrpServerInfo - "Nat64Prefix", // (14) kKeyNat64Prefix + "LegacyNat64Prefix", // (14) kKeyLegacyNat64Prefix + "BrUlaPrefix", // (15) kKeyBrUlaPrefix }; static_assert(1 == kKeyActiveDataset, "kKeyActiveDataset value is incorrect"); @@ -165,14 +166,15 @@ const char *SettingsBase::KeyToString(Key aKey) static_assert(6 == kKeyReserved, "kKeyReserved value is incorrect"); static_assert(7 == kKeySlaacIidSecretKey, "kKeySlaacIidSecretKey value is incorrect"); static_assert(8 == kKeyDadInfo, "kKeyDadInfo value is incorrect"); - static_assert(9 == kKeyOmrPrefix, "kKeyOmrPrefix value is incorrect"); + static_assert(9 == kKeyLegacyOmrPrefix, "kKeyLegacyOmrPrefix value is incorrect"); static_assert(10 == kKeyOnLinkPrefix, "kKeyOnLinkPrefix value is incorrect"); static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect"); static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect"); static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect"); - static_assert(14 == kKeyNat64Prefix, "kKeyNat64Prefix value is incorrect"); + static_assert(14 == kKeyLegacyNat64Prefix, "kKeyLegacyNat64Prefix value is incorrect"); + static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect"); - static_assert(kLastKey == kKeyNat64Prefix, "kLastKey is not valid"); + static_assert(kLastKey == kKeyBrUlaPrefix, "kLastKey is not valid"); OT_ASSERT(aKey <= kLastKey); @@ -429,9 +431,10 @@ void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue) #endif #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - case kKeyOmrPrefix: + case kKeyBrUlaPrefix: + case kKeyLegacyOmrPrefix: case kKeyOnLinkPrefix: - case kKeyNat64Prefix: + case kKeyLegacyNat64Prefix: LogPrefix(aAction, aKey, *reinterpret_cast(aValue)); break; #endif diff --git a/src/core/common/settings.hpp b/src/core/common/settings.hpp index c1e0a660f..335fd3780 100644 --- a/src/core/common/settings.hpp +++ b/src/core/common/settings.hpp @@ -118,15 +118,16 @@ public: kKeyReserved = OT_SETTINGS_KEY_RESERVED, kKeySlaacIidSecretKey = OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY, kKeyDadInfo = OT_SETTINGS_KEY_DAD_INFO, - kKeyOmrPrefix = OT_SETTINGS_KEY_OMR_PREFIX, + kKeyLegacyOmrPrefix = OT_SETTINGS_KEY_LEGACY_OMR_PREFIX, kKeyOnLinkPrefix = OT_SETTINGS_KEY_ON_LINK_PREFIX, kKeySrpEcdsaKey = OT_SETTINGS_KEY_SRP_ECDSA_KEY, kKeySrpClientInfo = OT_SETTINGS_KEY_SRP_CLIENT_INFO, kKeySrpServerInfo = OT_SETTINGS_KEY_SRP_SERVER_INFO, - kKeyNat64Prefix = OT_SETTINGS_KEY_NAT64_PREFIX, + kKeyLegacyNat64Prefix = OT_SETTINGS_KEY_LEGACY_NAT64_PREFIX, + kKeyBrUlaPrefix = OT_SETTINGS_KEY_BR_ULA_PREFIX, }; - static constexpr Key kLastKey = kKeyNat64Prefix; ///< The last (numerically) enumerator value in `Key`. + static constexpr Key kLastKey = kKeyBrUlaPrefix; ///< The last (numerically) enumerator value in `Key`. /** * This structure represents the device's own network information for settings storage. @@ -570,18 +571,33 @@ public: #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE /** - * This class defines constants and types for OMR prefix settings. + * This class defines constants and types for BR ULA prefix settings. * */ - class OmrPrefix + class BrUlaPrefix { public: - static constexpr Key kKey = kKeyOmrPrefix; ///< The associated key. + static constexpr Key kKey = kKeyBrUlaPrefix; ///< The associated key. typedef Ip6::Prefix ValueType; ///< The associated value type. private: - OmrPrefix(void) = default; + BrUlaPrefix(void) = default; + }; + + /** + * This class defines constants and types for legacy OMR prefix settings. + * + */ + class LegacyOmrPrefix + { + public: + static constexpr Key kKey = kKeyLegacyOmrPrefix; ///< The associated key. + + typedef Ip6::Prefix ValueType; ///< The associated value type. + + private: + LegacyOmrPrefix(void) = default; }; /** @@ -598,23 +614,6 @@ public: private: OnLinkPrefix(void) = default; }; - -#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE - /** - * This class defines constants and types for NAT64 prefix settings. - * - */ - class Nat64Prefix - { - public: - static constexpr Key kKey = kKeyNat64Prefix; ///< The associated key. - - typedef Ip6::Prefix ValueType; ///< The associated value type. - - private: - Nat64Prefix(void) = default; - }; -#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index f733a74e1..681c2708b 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -110,6 +110,14 @@ public: */ const uint8_t *GetBytes(void) const { return mPrefix.mFields.m8; } + /** + * This method gets the subnet ID of the prefix. + * + * @returns The 16-bit subnet ID. + * + */ + uint16_t GetSubnetId(void) const { return HostSwap16(mPrefix.mFields.m16[3]); } + /** * This method gets the prefix length (in bits). * @@ -143,6 +151,14 @@ public: */ void Set(const NetworkPrefix &aNetworkPrefix) { Set(aNetworkPrefix.m8, NetworkPrefix::kLength); } + /** + * This method sets the subnet ID of the prefix. + * + * @param[in] aSubnetId A 16-bit subnet ID. + * + */ + void SetSubnetId(uint16_t aSubnetId) { mPrefix.mFields.m16[3] = HostSwap16(aSubnetId); } + /** * This method set the prefix length. *