From 904e12d0475587d610227f657908752466fa4408 Mon Sep 17 00:00:00 2001 From: Rongli Sun Date: Thu, 30 Apr 2020 11:06:10 +0800 Subject: [PATCH] [slaac] allow customized parameters when `GenerateIid()` (#4854) --- src/core/utils/slaac_address.cpp | 47 ++++++++++++++++++++++++-------- src/core/utils/slaac_address.hpp | 25 +++++++++++++++-- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/core/utils/slaac_address.cpp b/src/core/utils/slaac_address.cpp index b60b00447..bf74e11d1 100644 --- a/src/core/utils/slaac_address.cpp +++ b/src/core/utils/slaac_address.cpp @@ -167,6 +167,12 @@ void Slaac::Update(UpdateMode aMode) { otIp6Prefix &prefix = config.mPrefix; + if (config.mDp) + { + // Skip domain prefix which is processed in MLE. + continue; + } + if (config.mSlaac && !ShouldFilter(prefix) && (prefix.mLength == slaacAddr->mPrefixLength) && (slaacAddr->GetAddress().PrefixMatch(prefix.mPrefix) >= prefix.mLength)) { @@ -196,7 +202,7 @@ void Slaac::Update(UpdateMode aMode) { otIp6Prefix &prefix = config.mPrefix; - if (!config.mSlaac || ShouldFilter(prefix)) + if (config.mDp || !config.mSlaac || ShouldFilter(prefix)) { continue; } @@ -252,7 +258,10 @@ void Slaac::Update(UpdateMode aMode) } } -void Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress) const +otError Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress, + uint8_t * aNetworkId, + uint8_t aNetworkIdLength, + uint8_t * aDadCounter) const { /* * This method generates a semantically opaque IID per RFC 7217. @@ -262,15 +271,16 @@ void Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress) const * - RID is random (but stable) Identifier. * - For pseudo-random function `F()` SHA-256 is used in this method. * - `Net_Iface` is set to constant string "wpan". - * - `Network_ID` is not used (optional per RF-7217). + * - `Network_ID` is not used if `aNetworkId` is NULL (optional per RF-7217). * - The `secret_key` is randomly generated on first use (using true * random number generator) and saved in non-volatile settings for * future use. * */ + otError error = OT_ERROR_FAILED; const uint8_t netIface[] = {'w', 'p', 'a', 'n'}; - uint16_t dadCounter; + uint8_t dadCounter = aDadCounter ? *aDadCounter : 0; IidSecretKey secretKey; Crypto::Sha256 sha256; uint8_t hash[Crypto::Sha256::kHashSize]; @@ -280,10 +290,16 @@ void Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress) const GetIidSecretKey(secretKey); - for (dadCounter = 0; dadCounter < kMaxIidCreationAttempts; dadCounter++) + for (uint16_t count = 0; count < kMaxIidCreationAttempts; count++, dadCounter++) { sha256.Start(); sha256.Update(aAddress.mAddress.mFields.m8, BitVectorBytes(aAddress.mPrefixLength)); + + if (aNetworkId) + { + sha256.Update(aNetworkId, aNetworkIdLength); + } + sha256.Update(netIface, sizeof(netIface)); sha256.Update(reinterpret_cast(&dadCounter), sizeof(dadCounter)); sha256.Update(secretKey.m8, sizeof(IidSecretKey)); @@ -291,18 +307,25 @@ void Slaac::GenerateIid(Ip6::NetifUnicastAddress &aAddress) const aAddress.GetAddress().SetIid(&hash[0]); - // Exit and return the address if the IID is not reserved, - // otherwise, try again with a new dadCounter + // If the IID is reserved, try again with a new dadCounter + if (aAddress.GetAddress().IsIidReserved()) + { + continue; + } - VerifyOrExit(aAddress.GetAddress().IsIidReserved(), OT_NOOP); + if (aDadCounter) + { + *aDadCounter = dadCounter; + } + + // Exit and return the address if the IID is not reserved, + ExitNow(error = OT_ERROR_NONE); } - otLogWarnUtil("SLAAC: Failed to generate a non-reserved IID after %d attempts", dadCounter); - Random::Crypto::FillBuffer(hash, Ip6::Address::kInterfaceIdentifierSize); - aAddress.GetAddress().SetIid(&hash[0]); + otLogWarnUtil("SLAAC: Failed to generate a non-reserved IID after %d attempts", kMaxIidCreationAttempts); exit: - return; + return error; } void Slaac::GetIidSecretKey(IidSecretKey &aKey) const diff --git a/src/core/utils/slaac_address.hpp b/src/core/utils/slaac_address.hpp index 90fd9f81b..09a9baea2 100644 --- a/src/core/utils/slaac_address.hpp +++ b/src/core/utils/slaac_address.hpp @@ -109,7 +109,7 @@ public: bool IsEnabled(void) const { return mEnabled; } /** - * This methods sets a SLAAC prefix filter handler. + * This method sets a SLAAC prefix filter handler. * * The handler is invoked by SLAAC module when it is about to add a SLAAC address based on a prefix. The return * boolean value from handler determines whether the address is filtered or added (TRUE to filter the address, @@ -120,10 +120,30 @@ public: */ void SetFilter(otIp6SlaacPrefixFilter aFilter); + /** + * This method generates the IID of an IPv6 address. + * + * @param[inout] aAddress A reference to the address that will be filled with the IID generated. + * Note the prefix of the address must already be filled and will be used + * to generate the IID. + * @param[in] aNetworkId A pointer to a byte array of Network_ID to generate IID. + * @param[in] aNetworkIdLength The size of array @p aNetworkId. + * @param[inout] aDadCounter A pointer to the DAD_Counter that is employed to resolve Duplicate + * Address Detection connflicts. + * + * @retval OT_ERROR_NONE If successfully generated the IID. + * @retval OT_ERROR_FAILED If no valid IID was generated. + * + */ + otError GenerateIid(Ip6::NetifUnicastAddress &aAddress, + uint8_t * aNetworkId = NULL, + uint8_t aNetworkIdLength = 0, + uint8_t * aDadCounter = NULL) const; + private: enum { - kMaxIidCreationAttempts = 1024, // Maximum number of attempts when generating IID. + kMaxIidCreationAttempts = 256, // Maximum number of attempts when generating IID. }; // Values for `UpdateMode` input parameter in `Update()`. @@ -140,7 +160,6 @@ private: bool ShouldFilter(const otIp6Prefix &aPrefix) const; void Update(UpdateMode aMode); - void GenerateIid(Ip6::NetifUnicastAddress &aAddress) const; void GetIidSecretKey(IidSecretKey &aKey) const; static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags); void HandleStateChanged(otChangedFlags aFlags);