[slaac] allow customized parameters when GenerateIid() (#4854)

This commit is contained in:
Rongli Sun
2020-04-29 22:57:50 -07:00
committed by Jonathan Hui
parent bbcfc3ca1e
commit 904e12d047
2 changed files with 57 additions and 15 deletions
+35 -12
View File
@@ -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<uint8_t *>(&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
+22 -3
View File
@@ -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);