mirror of
https://github.com/espressif/openthread.git
synced 2026-08-21 18:09:52 +00:00
[slaac] allow customized parameters when GenerateIid() (#4854)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user