[ip6] adding Ip6::Prefix class (#5306)

This commit adds `Ip6::Prefix` class as a sub-class of `otIp6Prefix`
representing an IPv6 Prefix. Helper methods are provided in `Prefix`
and `Address` to perform prefix matching.

Different core modules such as `network-data`, `lowpan`, `dhcp6`,
`slaac`, and, `backbone-router` are updated to use the new `Prefix`
and its helper methods.

This commit also updates the unit test `test_ip6_address` to verify
behavior of `Prefix` and its helper methods.
This commit is contained in:
Abtin Keshavarzian
2020-07-30 08:25:02 -07:00
committed by GitHub
parent b49ee0879a
commit 8c094c6ac2
30 changed files with 741 additions and 344 deletions
+2 -1
View File
@@ -107,7 +107,8 @@ otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterCon
OT_ASSERT(aConfig != nullptr);
return instance.Get<BackboneRouter::Local>().GetDomainPrefix(*aConfig);
return instance.Get<BackboneRouter::Local>().GetDomainPrefix(
*static_cast<NetworkData::OnMeshPrefixConfig *>(aConfig));
}
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+18 -15
View File
@@ -53,8 +53,9 @@ otError otBorderRouterGetNetData(otInstance *aInstance, bool aStable, uint8_t *a
otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig)
{
otError error = OT_ERROR_NONE;
Instance &instance = *static_cast<Instance *>(aInstance);
otError error = OT_ERROR_NONE;
Instance & instance = *static_cast<Instance *>(aInstance);
const NetworkData::OnMeshPrefixConfig *config = static_cast<const NetworkData::OnMeshPrefixConfig *>(aConfig);
OT_ASSERT(aConfig != nullptr);
// Add Prefix validation check:
@@ -62,16 +63,15 @@ otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRoute
// "A valid prefix MUST NOT allow both DHCPv6 and SLAAC for address configuration"
VerifyOrExit(!aConfig->mDhcp || !aConfig->mSlaac, error = OT_ERROR_INVALID_ARGS);
error = instance.Get<NetworkData::Local>().AddOnMeshPrefix(*aConfig);
error = instance.Get<NetworkData::Local>().AddOnMeshPrefix(*config);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
// Only try to configure Domain Prefix after the parameter is vaidated via above `AddOnMeshPrefix()`.
if (error == OT_ERROR_NONE && aConfig->mDp)
{
// Restore local server data
IgnoreError(instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aConfig->mPrefix.mPrefix.mFields.m8,
aConfig->mPrefix.mLength));
IgnoreError(instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(config->GetPrefix()));
instance.Get<BackboneRouter::Local>().SetDomainPrefix(*aConfig);
instance.Get<BackboneRouter::Local>().SetDomainPrefix(*config);
}
#endif
@@ -81,18 +81,19 @@ exit:
otError otBorderRouterRemoveOnMeshPrefix(otInstance *aInstance, const otIp6Prefix *aPrefix)
{
otError error = OT_ERROR_NONE;
Instance &instance = *static_cast<Instance *>(aInstance);
otError error = OT_ERROR_NONE;
Instance & instance = *static_cast<Instance *>(aInstance);
const Ip6::Prefix *prefix = static_cast<const Ip6::Prefix *>(aPrefix);
OT_ASSERT(aPrefix != nullptr);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
error = instance.Get<BackboneRouter::Local>().RemoveDomainPrefix(*aPrefix);
error = instance.Get<BackboneRouter::Local>().RemoveDomainPrefix(*prefix);
if (error == OT_ERROR_NOT_FOUND)
#endif
{
error = instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
error = instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(*prefix);
}
return error;
@@ -102,11 +103,12 @@ otError otBorderRouterGetNextOnMeshPrefix(otInstance * aInstance,
otNetworkDataIterator *aIterator,
otBorderRouterConfig * aConfig)
{
Instance &instance = *static_cast<Instance *>(aInstance);
Instance & instance = *static_cast<Instance *>(aInstance);
NetworkData::OnMeshPrefixConfig *config = static_cast<NetworkData::OnMeshPrefixConfig *>(aConfig);
OT_ASSERT(aIterator != nullptr && aConfig != nullptr);
return instance.Get<NetworkData::Local>().GetNextOnMeshPrefix(*aIterator, *aConfig);
return instance.Get<NetworkData::Local>().GetNextOnMeshPrefix(*aIterator, *config);
}
otError otBorderRouterAddRoute(otInstance *aInstance, const otExternalRouteConfig *aConfig)
@@ -116,7 +118,7 @@ otError otBorderRouterAddRoute(otInstance *aInstance, const otExternalRouteConfi
OT_ASSERT(aConfig != nullptr);
return instance.Get<NetworkData::Local>().AddHasRoutePrefix(
aConfig->mPrefix.mPrefix.mFields.m8, aConfig->mPrefix.mLength, aConfig->mPreference, aConfig->mStable);
*static_cast<const NetworkData::ExternalRouteConfig *>(aConfig));
}
otError otBorderRouterRemoveRoute(otInstance *aInstance, const otIp6Prefix *aPrefix)
@@ -125,7 +127,7 @@ otError otBorderRouterRemoveRoute(otInstance *aInstance, const otIp6Prefix *aPre
OT_ASSERT(aPrefix != nullptr);
return instance.Get<NetworkData::Local>().RemoveHasRoutePrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
return instance.Get<NetworkData::Local>().RemoveHasRoutePrefix(*static_cast<const Ip6::Prefix *>(aPrefix));
}
otError otBorderRouterGetNextRoute(otInstance * aInstance,
@@ -136,7 +138,8 @@ otError otBorderRouterGetNextRoute(otInstance * aInstance,
OT_ASSERT(aIterator != nullptr && aConfig != nullptr);
return instance.Get<NetworkData::Local>().GetNextExternalRoute(*aIterator, *aConfig);
return instance.Get<NetworkData::Local>().GetNextExternalRoute(
*aIterator, *static_cast<NetworkData::ExternalRouteConfig *>(aConfig));
}
otError otBorderRouterRegister(otInstance *aInstance)
+8 -5
View File
@@ -53,12 +53,13 @@ otError otNetDataGetNextOnMeshPrefix(otInstance * aInstance,
otNetworkDataIterator *aIterator,
otBorderRouterConfig * aConfig)
{
otError error = OT_ERROR_NONE;
Instance &instance = *static_cast<Instance *>(aInstance);
otError error = OT_ERROR_NONE;
Instance & instance = *static_cast<Instance *>(aInstance);
NetworkData::OnMeshPrefixConfig *config = static_cast<NetworkData::OnMeshPrefixConfig *>(aConfig);
VerifyOrExit(aIterator && aConfig, error = OT_ERROR_INVALID_ARGS);
error = instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(*aIterator, *aConfig);
error = instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(*aIterator, *config);
exit:
return error;
@@ -71,7 +72,8 @@ otError otNetDataGetNextRoute(otInstance *aInstance, otNetworkDataIterator *aIte
VerifyOrExit(aIterator && aConfig, error = OT_ERROR_INVALID_ARGS);
error = instance.Get<NetworkData::Leader>().GetNextExternalRoute(*aIterator, *aConfig);
error = instance.Get<NetworkData::Leader>().GetNextExternalRoute(
*aIterator, *static_cast<NetworkData::ExternalRouteConfig *>(aConfig));
exit:
return error;
@@ -84,7 +86,8 @@ otError otNetDataGetNextService(otInstance *aInstance, otNetworkDataIterator *aI
VerifyOrExit(aIterator && aConfig, error = OT_ERROR_INVALID_ARGS);
error = instance.Get<NetworkData::Leader>().GetNextService(*aIterator, *aConfig);
error = instance.Get<NetworkData::Leader>().GetNextService(*aIterator,
*static_cast<NetworkData::ServiceConfig *>(aConfig));
exit:
return error;
+2 -1
View File
@@ -78,7 +78,8 @@ otError otServerGetNextService(otInstance *aInstance, otNetworkDataIterator *aIt
VerifyOrExit(aIterator && aConfig, error = OT_ERROR_INVALID_ARGS);
error = instance.Get<NetworkData::Local>().GetNextService(*aIterator, *aConfig);
error = instance.Get<NetworkData::Local>().GetNextService(*aIterator,
*static_cast<NetworkData::ServiceConfig *>(aConfig));
exit:
return error;
+9 -14
View File
@@ -54,7 +54,7 @@ void Leader::Reset(void)
mConfig.mServer16 = Mac::kShortAddrInvalid;
// Domain Prefix Length 0 indicates no available Domain Prefix in the Thread network.
mDomainPrefix.mLength = 0;
mDomainPrefix.SetLength(0);
}
otError Leader::GetConfig(BackboneRouterConfig &aConfig) const
@@ -97,12 +97,9 @@ void Leader::LogBackboneRouterPrimary(State aState, const BackboneRouterConfig &
}
}
void Leader::LogDomainPrefix(DomainPrefixState aState, const otIp6Prefix &aPrefix) const
void Leader::LogDomainPrefix(DomainPrefixState aState, const Ip6::Prefix &aPrefix) const
{
otLogInfoBbr("Domain Prefix: %s/%d, state: %s",
aPrefix.mLength == 0 ? ""
: static_cast<const Ip6::Address *>(&aPrefix.mPrefix)->ToString().AsCString(),
aPrefix.mLength, DomainPrefixStateToString(aState));
otLogInfoBbr("Domain Prefix: %s, state: %s", aPrefix.ToString().AsCString(), DomainPrefixStateToString(aState));
}
const char *Leader::StateToString(State aState)
@@ -250,20 +247,18 @@ void Leader::UpdateDomainPrefixConfig(void)
if (!found)
{
if (mDomainPrefix.mLength != 0)
if (mDomainPrefix.GetLength() != 0)
{
// Domain Prefix does not exist any more.
mDomainPrefix.mLength = 0;
state = kDomainPrefixRemoved;
mDomainPrefix.SetLength(0);
state = kDomainPrefixRemoved;
}
else
{
state = kDomainPrefixNone;
}
}
else if (config.mPrefix.mLength == mDomainPrefix.mLength &&
Ip6::Address::PrefixMatch(mDomainPrefix.mPrefix.mFields.m8, config.mPrefix.mPrefix.mFields.m8,
BitVectorBytes(mDomainPrefix.mLength)) >= mDomainPrefix.mLength)
else if (config.GetPrefix() == mDomainPrefix)
{
state = kDomainPrefixUnchanged;
}
@@ -278,7 +273,7 @@ void Leader::UpdateDomainPrefixConfig(void)
state = kDomainPrefixRefreshed;
}
mDomainPrefix = config.mPrefix;
mDomainPrefix = config.GetPrefix();
}
LogDomainPrefix(state, mDomainPrefix);
@@ -294,7 +289,7 @@ void Leader::UpdateDomainPrefixConfig(void)
bool Leader::IsDomainUnicast(const Ip6::Address &aAddress) const
{
return HasDomainPrefix() && aAddress.PrefixMatch(mDomainPrefix.mPrefix) >= mDomainPrefix.mLength;
return HasDomainPrefix() && aAddress.MatchesPrefix(mDomainPrefix);
}
} // namespace BackboneRouter
+8 -5
View File
@@ -142,7 +142,10 @@ public:
* @retval A pointer to the Domain Prefix or nullptr if there is no Domain Prefix.
*
*/
const otIp6Prefix *GetDomainPrefix(void) const { return (mDomainPrefix.mLength == 0) ? nullptr : &mDomainPrefix; }
const Ip6::Prefix *GetDomainPrefix(void) const
{
return (mDomainPrefix.GetLength() == 0) ? nullptr : &mDomainPrefix;
}
/**
* This method indicates whether or not the Domain Prefix is available in the Thread Network.
@@ -150,7 +153,7 @@ public:
* @retval TRUE if there is Domain Prefix, FALSE otherwise.
*
*/
bool HasDomainPrefix(void) const { return (mDomainPrefix.mLength > 0); }
bool HasDomainPrefix(void) const { return (mDomainPrefix.GetLength() > 0); }
/**
* This method indicates whether or not the address is a Domain Unicast Address.
@@ -168,16 +171,16 @@ private:
void UpdateDomainPrefixConfig(void);
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_BBR == 1)
void LogBackboneRouterPrimary(State aState, const BackboneRouterConfig &aConfig) const;
void LogDomainPrefix(DomainPrefixState aState, const otIp6Prefix &aPrefix) const;
void LogDomainPrefix(DomainPrefixState aState, const Ip6::Prefix &aPrefix) const;
static const char *StateToString(State aState);
static const char *DomainPrefixStateToString(DomainPrefixState aState);
#else
void LogBackboneRouterPrimary(State, const BackboneRouterConfig &) const {}
void LogDomainPrefix(DomainPrefixState, const otIp6Prefix &) const {}
void LogDomainPrefix(DomainPrefixState, const Ip6::Prefix &) const {}
#endif
BackboneRouterConfig mConfig; ///< Primary Backbone Router information.
otIp6Prefix mDomainPrefix; ///< Domain Prefix in the Thread network.
Ip6::Prefix mDomainPrefix; ///< Domain Prefix in the Thread network.
};
} // namespace BackboneRouter
+10 -19
View File
@@ -56,7 +56,7 @@ Local::Local(Instance &aInstance)
, mRegistrationJitter(Mle::kBackboneRouterRegistrationJitter)
, mIsServiceAdded(false)
{
mDomainPrefixConfig.mPrefix.mLength = 0;
mDomainPrefixConfig.GetPrefix().SetLength(0);
// Primary Backbone Router Aloc
mBackboneRouterPrimaryAloc.Clear();
@@ -312,7 +312,7 @@ otError Local::GetDomainPrefix(NetworkData::OnMeshPrefixConfig &aConfig)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mDomainPrefixConfig.mPrefix.mLength > 0, error = OT_ERROR_NOT_FOUND);
VerifyOrExit(mDomainPrefixConfig.GetPrefix().GetLength() > 0, error = OT_ERROR_NOT_FOUND);
aConfig = mDomainPrefixConfig;
@@ -320,24 +320,19 @@ exit:
return error;
}
otError Local::RemoveDomainPrefix(const otIp6Prefix &aPrefix)
otError Local::RemoveDomainPrefix(const Ip6::Prefix &aPrefix)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(aPrefix.mLength > 0, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(mDomainPrefixConfig.mPrefix.mLength == aPrefix.mLength, error = OT_ERROR_NOT_FOUND);
VerifyOrExit(Ip6::Address::PrefixMatch(mDomainPrefixConfig.mPrefix.mPrefix.mFields.m8, aPrefix.mPrefix.mFields.m8,
BitVectorBytes(aPrefix.mLength)) >= aPrefix.mLength,
error = OT_ERROR_NOT_FOUND);
VerifyOrExit(aPrefix.GetLength() > 0, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(mDomainPrefixConfig.GetPrefix() == aPrefix, error = OT_ERROR_NOT_FOUND);
if (IsEnabled())
{
RemoveDomainPrefixFromNetworkData();
}
mDomainPrefixConfig.mPrefix.mLength = 0;
mDomainPrefixConfig.GetPrefix().SetLength(0);
exit:
return error;
@@ -407,8 +402,7 @@ void Local::RemoveDomainPrefixFromNetworkData(void)
if (mDomainPrefixConfig.mPrefix.mLength > 0)
{
error = Get<NetworkData::Local>().RemoveOnMeshPrefix(mDomainPrefixConfig.mPrefix.mPrefix.mFields.m8,
mDomainPrefixConfig.mPrefix.mLength);
error = Get<NetworkData::Local>().RemoveOnMeshPrefix(mDomainPrefixConfig.GetPrefix());
}
LogDomainPrefix("Remove", error);
@@ -418,7 +412,7 @@ void Local::AddDomainPrefixToNetworkData(void)
{
otError error = OT_ERROR_NOT_FOUND; // only used for logging.
if (mDomainPrefixConfig.mPrefix.mLength > 0)
if (mDomainPrefixConfig.GetPrefix().GetLength() > 0)
{
error = Get<NetworkData::Local>().AddOnMeshPrefix(mDomainPrefixConfig);
}
@@ -429,11 +423,8 @@ void Local::AddDomainPrefixToNetworkData(void)
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_BBR == 1)
void Local::LogDomainPrefix(const char *aAction, otError aError)
{
otLogInfoBbr("%s Domain Prefix: %s/%d, %s", aAction,
mDomainPrefixConfig.mPrefix.mLength > 0
? (*static_cast<Ip6::Address *>(&mDomainPrefixConfig.mPrefix.mPrefix)).ToString().AsCString()
: "",
mDomainPrefixConfig.mPrefix.mLength, otThreadErrorToString(aError));
otLogInfoBbr("%s Domain Prefix: %s, %s", aAction, mDomainPrefixConfig.GetPrefix().ToString().AsCString(),
otThreadErrorToString(aError));
}
void Local::LogBackboneRouterService(const char *aAction, otError aError)
+1 -1
View File
@@ -188,7 +188,7 @@ public:
* @retval OT_ERROR_NOT_FOUND No Domain Prefix was configured or @p aPrefix doesn't match.
*
*/
otError RemoveDomainPrefix(const otIp6Prefix &aPrefix);
otError RemoveDomainPrefix(const Ip6::Prefix &aPrefix);
/**
* This method sets the local Domain Prefix configuration.
+4 -5
View File
@@ -57,10 +57,9 @@ Client::Client(Instance &aInstance)
memset(mIdentityAssociations, 0, sizeof(mIdentityAssociations));
}
bool Client::MatchNetifAddressWithPrefix(const Ip6::NetifUnicastAddress &aNetifAddress, const otIp6Prefix &aIp6Prefix)
bool Client::MatchNetifAddressWithPrefix(const Ip6::NetifUnicastAddress &aNetifAddress, const Ip6::Prefix &aIp6Prefix)
{
return (aIp6Prefix.mLength == aNetifAddress.mPrefixLength) &&
(aNetifAddress.GetAddress().PrefixMatch(aIp6Prefix.mPrefix) >= aIp6Prefix.mLength);
return aNetifAddress.HasPrefix(aIp6Prefix);
}
void Client::UpdateAddresses(void)
@@ -88,7 +87,7 @@ void Client::UpdateAddresses(void)
continue;
}
if (MatchNetifAddressWithPrefix(idAssociation.mNetifAddress, config.mPrefix))
if (MatchNetifAddressWithPrefix(idAssociation.mNetifAddress, config.GetPrefix()))
{
found = true;
break;
@@ -127,7 +126,7 @@ void Client::UpdateAddresses(void)
idAssociation = &ia;
}
}
else if (MatchNetifAddressWithPrefix(ia.mNetifAddress, config.mPrefix))
else if (MatchNetifAddressWithPrefix(ia.mNetifAddress, config.GetPrefix()))
{
found = true;
idAssociation = &ia;
+1 -1
View File
@@ -109,7 +109,7 @@ private:
void Start(void);
void Stop(void);
static bool MatchNetifAddressWithPrefix(const Ip6::NetifUnicastAddress &aAddress, const otIp6Prefix &aIp6Prefix);
static bool MatchNetifAddressWithPrefix(const Ip6::NetifUnicastAddress &aAddress, const Ip6::Prefix &aIp6Prefix);
void Solicit(uint16_t aRloc16);
+6 -6
View File
@@ -82,7 +82,7 @@ otError Server::UpdateService(void)
continue;
}
error = Get<NetworkData::Leader>().GetContext(prefixAgent.GetPrefix(), lowpanContext);
error = Get<NetworkData::Leader>().GetContext(prefixAgent.GetPrefixAsAddress(), lowpanContext);
if ((error == OT_ERROR_NONE) && (prefixAgent.GetContextId() == lowpanContext.mContextId))
{
@@ -114,7 +114,7 @@ otError Server::UpdateService(void)
if (error == OT_ERROR_NONE)
{
AddPrefixAgent(config.mPrefix, lowpanContext);
AddPrefixAgent(config.GetPrefix(), lowpanContext);
}
}
@@ -144,7 +144,7 @@ void Server::Stop(void)
IgnoreError(mSocket.Close());
}
void Server::AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext)
void Server::AddPrefixAgent(const Ip6::Prefix &aIp6Prefix, const Lowpan::Context &aContext)
{
otError error = OT_ERROR_NONE;
PrefixAgent *newEntry = nullptr;
@@ -155,7 +155,7 @@ void Server::AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context
{
newEntry = &prefixAgent;
}
else if (prefixAgent.IsPrefixMatch(aIp6Prefix))
else if (prefixAgent.GetPrefix() == aIp6Prefix)
{
// already added
ExitNow();
@@ -445,7 +445,7 @@ otError Server::AppendIaAddress(Message &aMessage, ClientIdentifier &aClientId)
{
if (mPrefixAgentsMask & (1 << i))
{
SuccessOrExit(error = AddIaAddress(aMessage, mPrefixAgents[i].GetPrefix(), aClientId));
SuccessOrExit(error = AddIaAddress(aMessage, mPrefixAgents[i].GetPrefixAsAddress(), aClientId));
}
}
}
@@ -456,7 +456,7 @@ otError Server::AppendIaAddress(Message &aMessage, ClientIdentifier &aClientId)
{
if (prefixAgent.IsValid())
{
SuccessOrExit(error = AddIaAddress(aMessage, prefixAgent.GetPrefix(), aClientId));
SuccessOrExit(error = AddIaAddress(aMessage, prefixAgent.GetPrefixAsAddress(), aClientId));
}
}
}
+24 -23
View File
@@ -84,21 +84,6 @@ private:
class PrefixAgent
{
public:
/**
* This method indicates whether or not @p aPrefix matches this entry.
*
* @param[in] aPrefix The prefix to compare.
*
* @retval TRUE if the prefix matches.
* @retval FALSE if the prefix does not match.
*
*/
bool IsPrefixMatch(const otIp6Prefix &aPrefix) const
{
return (mPrefix.mLength == aPrefix.mLength) &&
(GetPrefix().PrefixMatch(static_cast<const Ip6::Address &>(aPrefix.mPrefix)) >= mPrefix.mLength);
}
/**
* This method indicates whether or not @p aAddress has a matching prefix.
*
@@ -108,10 +93,7 @@ private:
* @retval FALSE if the address does not have a matching prefix.
*
*/
bool IsPrefixMatch(const Ip6::Address &aAddress) const
{
return (aAddress.PrefixMatch(static_cast<const Ip6::Address &>(mPrefix.mPrefix)) >= mPrefix.mLength);
}
bool IsPrefixMatch(const Ip6::Address &aAddress) const { return aAddress.MatchesPrefix(GetPrefix()); }
/**
* This method indicates whether or not this entry is valid.
@@ -150,7 +132,26 @@ private:
* @returns The IPv6 prefix.
*
*/
const Ip6::Address &GetPrefix(void) const { return static_cast<const Ip6::Address &>(mPrefix.mPrefix); }
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
/**
* This method returns the IPv6 prefix.
*
* @returns The IPv6 prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return mPrefix; }
/**
* This method returns the IPv6 prefix as an IPv6 address.
*
* @returns The IPv6 prefix as an IPv6 address.
*
*/
const Ip6::Address &GetPrefixAsAddress(void) const
{
return static_cast<const Ip6::Address &>(mPrefix.mPrefix);
}
/**
* This method sets the ALOC.
@@ -160,7 +161,7 @@ private:
* @param[in] aContextId The 6LoWPAN Context ID.
*
*/
void Set(const otIp6Prefix &aPrefix, const Mle::MeshLocalPrefix &aMeshLocalPrefix, uint8_t aContextId)
void Set(const Ip6::Prefix &aPrefix, const Mle::MeshLocalPrefix &aMeshLocalPrefix, uint8_t aContextId)
{
mPrefix = aPrefix;
@@ -173,7 +174,7 @@ private:
private:
Ip6::NetifUnicastAddress mAloc;
otIp6Prefix mPrefix;
Ip6::Prefix mPrefix;
};
enum : uint16_t
@@ -184,7 +185,7 @@ private:
void Start(void);
void Stop(void);
void AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext);
void AddPrefixAgent(const Ip6::Prefix &aIp6Prefix, const Lowpan::Context &aContext);
otError AppendHeader(Message &aMessage, const TransactionId &aTransactionId);
otError AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClientId);
+77 -37
View File
@@ -56,6 +56,69 @@ otError NetworkPrefix::GenerateRandomUla(void)
return Random::Crypto::FillBuffer(&m8[1], kSize - 1);
}
//---------------------------------------------------------------------------------------------------------------------
// Prefix methods
void Prefix::Set(const uint8_t *aPrefix, uint8_t aLength)
{
memcpy(mPrefix.mFields.m8, aPrefix, SizeForLength(aLength));
mLength = aLength;
}
bool Prefix::IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const
{
return (mLength == aPrefixLength) && (MatchLength(GetBytes(), aPrefixBytes, GetBytesSize()) >= mLength);
}
uint8_t Prefix::MatchLength(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxSize)
{
uint8_t matchedLength = 0;
OT_ASSERT(aMaxSize <= Address::kSize);
for (uint8_t i = 0; i < aMaxSize; i++)
{
uint8_t diff = aPrefixA[i] ^ aPrefixB[i];
if (diff == 0)
{
matchedLength += CHAR_BIT;
}
else
{
while ((diff & 0x80) == 0)
{
matchedLength++;
diff <<= 1;
}
break;
}
}
return matchedLength;
}
Prefix::InfoString Prefix::ToString(void) const
{
InfoString string;
uint8_t sizeInUint16 = (GetBytesSize() + sizeof(uint16_t) - 1) / sizeof(uint16_t);
for (uint16_t i = 0; i < sizeInUint16; i++)
{
IgnoreError(string.Append("%s%x", (i > 0) ? ":" : "", HostSwap16(mPrefix.mFields.m16[i])));
}
if (GetBytesSize() < Address::kSize - 1)
{
IgnoreError(string.Append("::"));
}
IgnoreError(string.Append("/%d", mLength));
return string;
}
//---------------------------------------------------------------------------------------------------------------------
// InterfaceIdentifier methods
@@ -262,14 +325,24 @@ void Address::SetToRealmLocalAllMplForwarders(void)
*this = GetRealmLocalAllMplForwarders();
}
bool Address::MatchesPrefix(const Prefix &aPrefix) const
{
return Prefix::MatchLength(mFields.m8, aPrefix.GetBytes(), aPrefix.GetBytesSize()) >= aPrefix.GetLength();
}
bool Address::MatchesPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const
{
return Prefix::MatchLength(mFields.m8, aPrefix, Prefix::SizeForLength(aPrefixLength)) >= aPrefixLength;
}
void Address::SetPrefix(const NetworkPrefix &aNetworkPrefix)
{
mFields.mComponents.mNetworkPrefix = aNetworkPrefix;
}
void Address::SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
void Address::SetPrefix(const Prefix &aPrefix)
{
SetPrefix(0, aPrefix, aPrefixLength);
SetPrefix(0, aPrefix.GetBytes(), aPrefix.GetLength());
}
void Address::SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength)
@@ -331,42 +404,9 @@ uint8_t Address::GetScope(void) const
return rval;
}
uint8_t Address::PrefixMatch(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxLength)
uint8_t Address::PrefixMatch(const Address &aOther) const
{
uint8_t rval = 0;
uint8_t diff;
if (aMaxLength > sizeof(Address))
{
aMaxLength = sizeof(Address);
}
for (uint8_t i = 0; i < aMaxLength; i++)
{
diff = aPrefixA[i] ^ aPrefixB[i];
if (diff == 0)
{
rval += 8;
}
else
{
while ((diff & 0x80) == 0)
{
rval++;
diff <<= 1;
}
break;
}
}
return rval;
}
uint8_t Address::PrefixMatch(const otIp6Address &aOther) const
{
return PrefixMatch(mFields.m8, aOther.mFields.m8, sizeof(Address));
return Prefix::MatchLength(mFields.m8, aOther.mFields.m8, sizeof(Address));
}
bool Address::MatchesFilter(TypeFilter aFilter) const
+223 -18
View File
@@ -82,6 +82,189 @@ public:
} OT_TOOL_PACKED_END;
/**
* This class represents an IPv6 Prefix.
*
*/
OT_TOOL_PACKED_BEGIN
class Prefix : public otIp6Prefix
{
public:
enum : uint8_t
{
kMaxLength = OT_IP6_ADDRESS_SIZE * CHAR_BIT, ///< Max length of a prefix in bits.
kMaxSize = OT_IP6_ADDRESS_SIZE, ///< Max (byte) size of a prefix.
};
enum : uint16_t
{
kInfoStringSize = 45, ///< Max chars for the info string (`ToString()`).
};
/**
* This type defines the fixed-length `String` object returned from `ToString()`.
*
*/
typedef String<kInfoStringSize> InfoString;
/**
* This method gets the prefix as a pointer to a byte array.
*
* @returns A pointer to a byte array containing the Prefix.
*
*/
const uint8_t *GetBytes(void) const { return mPrefix.mFields.m8; }
/**
* This method gets the prefix length (in bits).
*
* @returns The prefix length (in bits).
*
*/
uint8_t GetLength(void) const { return mLength; }
/**
* This method returns the size (in bytes) of the prefix.
*
* @returns The size (in bytes) of the prefix array.
*
*/
uint8_t GetBytesSize(void) const { return SizeForLength(mLength); }
/**
* This method sets the prefix.
*
* @param[in] aPrefix A pointer to buffer containing the prefix bytes.
* @param[in] aLength The length or prefix in bits.
*
*/
void Set(const uint8_t *aPrefix, uint8_t aLength);
/**
* This method sets the prefix from a given Network Prefix.
*
* @param[in] aNetworkPrefix A Network Prefix.
*
*/
void Set(const NetworkPrefix &aNetworkPrefix) { Set(aNetworkPrefix.m8, NetworkPrefix::kLength); }
/**
* This method set the prefix length.
*
* @param[in] aLength The new prefix length (in bits).
*
*/
void SetLength(uint8_t aLength) { mLength = aLength; }
/**
* This method indicates whether prefix length is valid (smaller or equal to max length).
*
* @retval TRUE The prefix length is valid.
* @retval FALSE The prefix length is not valid.
*
*/
bool IsValid(void) const { return (mLength <= kMaxLength); }
/**
* This method indicates whether the prefix is equal to a given prefix.
*
* @param[in] aPrefixBytes A pointer to buffer containing the prefix bytes to compare with.
* @param[in] aPrefixLength The length of prefix (in bits) specified by @p aPrefixBytes.
*
* @retval TRUE If the prefix is equal to the specified prefix by @p aPrefixBytes and @p aPrefixLength.
* @retval FALSE If the prefix is not equal to the specified prefix by @p aPrefixBytes and @p aPrefixLength.
*
*/
bool IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const;
/**
* This method indicates whether the prefix contains a sub-prefix.
*
* @param[in] aSubPrefix A sub-prefix.
*
* @retval TRUE The prefix contains the @p aSubPrefix
* @retval FALSE The prefix does not contains the @p aSubPrefix.
*
*/
bool ContainsPrefix(const Prefix &aSubPrefix) const
{
return (mLength >= aSubPrefix.mLength) &&
(MatchLength(GetBytes(), aSubPrefix.GetBytes(), aSubPrefix.GetBytesSize()) >= aSubPrefix.GetLength());
}
/**
* This method indicates whether the prefix contains a sub-prefix (given as a `NetworkPrefix`).
*
* @param[in] aSubPrefix A sub-prefix (as a `NetworkPrefix`).
*
* @retval TRUE The prefix contains the @p aSubPrefix
* @retval FALSE The prefix does not contains the @p aSubPrefix.
*
*/
bool ContainsPrefix(const NetworkPrefix &aSubPrefix) const
{
return (mLength >= NetworkPrefix::kLength) &&
(MatchLength(GetBytes(), aSubPrefix.m8, NetworkPrefix::kSize) >= NetworkPrefix::kLength);
}
/**
* This method overloads operator `==` to evaluate whether or not two prefixes are equal.
*
* @param[in] aOther The other prefix to compare with.
*
* @retval TRUE If the two prefixes are equal.
* @retval FALSE If the two prefixes are not equal.
*
*/
bool operator==(const Prefix &aOther) const
{
return (mLength == aOther.mLength) &&
(MatchLength(GetBytes(), aOther.GetBytes(), GetBytesSize()) >= GetLength());
}
/**
* This method overloads operator `==` to evaluate whether or not two prefixes are unequal.
*
* @param[in] aOther The other prefix to compare with.
*
* @retval TRUE If the two prefixes are unequal.
* @retval FALSE If the two prefixes are not unequal.
*
*/
bool operator!=(const Prefix &aOther) const { return !(*this == aOther); }
/**
* This static method converts a prefix length (in bits) to size (number of bytes).
*
* @param[in] aLength A prefix length (in bits).
*
* @returns The size (in bytes) of the prefix.
*
*/
static uint8_t SizeForLength(uint8_t aLength) { return BitVectorBytes(aLength); }
/**
* This static method returns the number of IPv6 prefix bits that match.
*
* @param[in] aPrefixA A pointer to a byte array containing a first prefix.
* @param[in] aPrefixB A pointer to a byte array containing a second prefix.
* @param[in] aMaxSize Number of bytes of the two prefixes.
*
* @returns The number of prefix bits that match.
*
*/
static uint8_t MatchLength(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxSize);
/**
* This method converts the prefix to a string.
*
* @returns An `InfoString` containing the string representation of the Prefix.
*
*/
InfoString ToString(void) const;
} OT_TOOL_PACKED_END;
/**
* This class represents the Interface Identifier of an IPv6 address.
*
@@ -534,17 +717,40 @@ public:
return static_cast<const NetworkPrefix &>(mFields.mComponents.mNetworkPrefix);
}
/**
* This method indicates whether the IPv6 address matches a given prefix.
*
* @param[in] aPrefix An IPv6 prefix to match with.
*
* @retval TRUE The IPv6 address matches the @p aPrefix.
* @retval FALSE The IPv6 address does not match the @p aPrefix.
*
*/
bool MatchesPrefix(const Prefix &aPrefix) const;
/**
* This method indicates whether the IPv6 address matches a given prefix.
*
* @param[in] aPrefix A buffer containing the prefix.
* @param[in] aPrefixLength The prefix length (in bits).
*
* @retval TRUE The IPv6 address matches the @p aPrefix.
* @retval FALSE The IPv6 address does not match the @p aPrefix.
*
*/
bool MatchesPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
/**
* This method sets the IPv6 address prefix.
*
* This method only changes the first @p aPrefixLength bits of the address and keeps the rest of the bits in the
* address as before.
*
* @param[in] aPrefix A buffer containing the prefix
* @param[in] aPrefix A buffer containing the prefix.
* @param[in] aPrefixLength The prefix length (in bits).
*
*/
void SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
void SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { SetPrefix(0, aPrefix, aPrefixLength); }
/**
* This method sets the IPv6 address prefix to the given Network Prefix.
@@ -554,6 +760,17 @@ public:
*/
void SetPrefix(const NetworkPrefix &aNetworkPrefix);
/**
* This method sets the IPv6 address prefix.
*
* This method only changes the initial prefix length bits of the IPv6 address and keeps the rest of the bits in
* the address as before.
*
* @param[in] aPrefix An IPv6 prefix.
*
*/
void SetPrefix(const Prefix &aPrefix);
/**
* This method sets the prefix content of the Prefix-Based Multicast Address.
*
@@ -577,12 +794,12 @@ public:
/**
* This method sets the prefix content of Prefix-Based Multicast Address.
*
* @param[in] aPrefix A reference to an IPv6 Prefix.
* @param[in] aPrefix An IPv6 Prefix.
*
*/
void SetMulticastNetworkPrefix(const otIp6Prefix &aPrefix)
void SetMulticastNetworkPrefix(const Prefix &aPrefix)
{
SetMulticastNetworkPrefix(aPrefix.mPrefix.mFields.m8, aPrefix.mLength);
SetMulticastNetworkPrefix(aPrefix.GetBytes(), aPrefix.GetLength());
}
/**
@@ -628,7 +845,7 @@ public:
* @returns The number of IPv6 prefix bits that match.
*
*/
uint8_t PrefixMatch(const otIp6Address &aOther) const;
uint8_t PrefixMatch(const Address &aOther) const;
/**
* This method indicates whether address matches a given type filter.
@@ -660,18 +877,6 @@ public:
*/
InfoString ToString(void) const;
/**
* This method returns the number of IPv6 prefix bits that match.
*
* @param[in] aPrefixA A pointer to the prefix to match.
* @param[in] aPrefixB A pointer to the prefix to match against.
* @param[in] aMaxLength Number of bytes of the two prefixes.
*
* @returns The number of prefix bits that match.
*
*/
static uint8_t PrefixMatch(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxLength);
private:
void SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength);
void SetToLocator(const NetworkPrefix &aNetworkPrefix, uint16_t aLocator);
+22
View File
@@ -91,6 +91,28 @@ public:
*/
Address &GetAddress(void) { return static_cast<Address &>(mAddress); }
/**
* This method returns the address's prefix length (in bits).
*
* @returns The prefix length (in bits).
*
*/
uint8_t GetPrefixLength(void) const { return mPrefixLength; }
/**
* This method indicates whether the address has a given prefix (i.e. same prefix length and matches the prefix).
*
* @param[in] aPrefix A prefix to check against.
*
* @retval TRUE The address has and fully matches the @p aPrefix.
* @retval FALSE The address does not contain or match the @p aPrefix.
*
*/
bool HasPrefix(const Prefix &aPrefix) const
{
return (mPrefixLength == aPrefix.GetLength()) && GetAddress().MatchesPrefix(aPrefix);
}
/**
* This method returns the IPv6 scope value.
*
+3 -3
View File
@@ -62,7 +62,7 @@ DuaManager::DuaManager(Instance &aInstance)
void DuaManager::UpdateDomainUnicastAddress(BackboneRouter::Leader::DomainPrefixState aState)
{
const otIp6Prefix *prefix;
const Ip6::Prefix *prefix;
if ((aState == BackboneRouter::Leader::kDomainPrefixRemoved) ||
(aState == BackboneRouter::Leader::kDomainPrefixRefreshed))
@@ -78,9 +78,9 @@ void DuaManager::UpdateDomainUnicastAddress(BackboneRouter::Leader::DomainPrefix
OT_ASSERT(prefix != nullptr);
mDomainUnicastAddress.mPrefixLength = prefix->mLength;
mDomainUnicastAddress.mPrefixLength = prefix->GetLength();
mDomainUnicastAddress.GetAddress().Clear();
mDomainUnicastAddress.GetAddress().SetPrefix(prefix->mPrefix.mFields.m8, prefix->mLength);
mDomainUnicastAddress.GetAddress().SetPrefix(*prefix);
// Apply cached DUA Interface Identifier manually specified.
if (IsFixedDuaInterfaceIdentifierSet())
+10 -10
View File
@@ -57,7 +57,7 @@ Lowpan::Lowpan(Instance &aInstance)
void Lowpan::CopyContext(const Context &aContext, Ip6::Address &aAddress)
{
aAddress.SetPrefix(aContext.mPrefix, aContext.mPrefixLength);
aAddress.SetPrefix(aContext.mPrefix);
}
otError Lowpan::ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress)
@@ -78,12 +78,12 @@ otError Lowpan::ComputeIid(const Mac::Address &aMacAddr, const Context &aContext
ExitNow(error = OT_ERROR_PARSE);
}
if (aContext.mPrefixLength > 64)
if (aContext.mPrefix.GetLength() > 64)
{
for (int i = (aContext.mPrefixLength & ~7); i < aContext.mPrefixLength; i++)
for (int i = (aContext.mPrefix.GetLength() & ~7); i < aContext.mPrefix.GetLength(); i++)
{
aIpAddress.mFields.m8[i / CHAR_BIT] &= ~(0x80 >> (i % CHAR_BIT));
aIpAddress.mFields.m8[i / CHAR_BIT] |= aContext.mPrefix[i / CHAR_BIT] & (0x80 >> (i % CHAR_BIT));
aIpAddress.mFields.m8[i / CHAR_BIT] |= aContext.mPrefix.GetBytes()[i / CHAR_BIT] & (0x80 >> (i % CHAR_BIT));
}
}
@@ -213,8 +213,8 @@ otError Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl,
{
// Check if multicast address can be compressed using Context ID 0.
if (Get<NetworkData::Leader>().GetContext(0, multicastContext) == OT_ERROR_NONE &&
multicastContext.mPrefixLength == aIpAddr.mFields.m8[3] &&
memcmp(multicastContext.mPrefix, aIpAddr.mFields.m8 + 4, 8) == 0)
multicastContext.mPrefix.GetLength() == aIpAddr.mFields.m8[3] &&
memcmp(multicastContext.mPrefix.GetBytes(), aIpAddr.mFields.m8 + 4, 8) == 0)
{
aHcCtl |= kHcDstAddrContext | kHcDstAddrMode0;
SuccessOrExit(error = buf.Write(aIpAddr.mFields.m8 + 1, 2));
@@ -684,8 +684,8 @@ int Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
VerifyOrExit((hcCtl & kHcDispatchMask) == kHcDispatch, OT_NOOP);
// Context Identifier
srcContext.mPrefixLength = 0;
dstContext.mPrefixLength = 0;
srcContext.mPrefix.SetLength(0);
dstContext.mPrefix.SetLength(0);
if ((hcCtl & kHcContextId) != 0)
{
@@ -909,8 +909,8 @@ int Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
VerifyOrExit(dstContextValid, OT_NOOP);
aIp6Header.GetDestination().mFields.m8[1] = cur[0];
aIp6Header.GetDestination().mFields.m8[2] = cur[1];
aIp6Header.GetDestination().mFields.m8[3] = dstContext.mPrefixLength;
memcpy(aIp6Header.GetDestination().mFields.m8 + 4, dstContext.mPrefix, 8);
aIp6Header.GetDestination().mFields.m8[3] = dstContext.mPrefix.GetLength();
memcpy(aIp6Header.GetDestination().mFields.m8 + 4, dstContext.mPrefix.GetBytes(), 8);
memcpy(aIp6Header.GetDestination().mFields.m8 + 12, cur + 2, 4);
cur += 6;
break;
+3 -4
View File
@@ -71,10 +71,9 @@ using ot::Encoding::BigEndian::HostSwap16;
*/
struct Context
{
const uint8_t *mPrefix; ///< A pointer to the prefix.
uint8_t mPrefixLength; ///< The prefix length.
uint8_t mContextId; ///< The Context ID.
bool mCompressFlag; ///< The Context compression flag.
Ip6::Prefix mPrefix; ///< The Prefix
uint8_t mContextId; ///< The Context ID.
bool mCompressFlag; ///< The Context compression flag.
};
/**
+2 -1
View File
@@ -2093,7 +2093,8 @@ otError MleRouter::UpdateChildAddresses(const Message &aMessage, uint16_t aOffse
continue;
}
memcpy(&address, context.mPrefix, BitVectorBytes(context.mPrefixLength));
address.Clear();
address.SetPrefix(context.mPrefix);
address.SetIid(entry.GetIid());
}
else
+21 -38
View File
@@ -218,7 +218,7 @@ otError NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aCon
{
if (cur->GetType() == NetworkDataTlv::kTypePrefix)
{
const PrefixTlv *prefix = static_cast<const PrefixTlv *>(cur);
const PrefixTlv *prefixTlv = static_cast<const PrefixTlv *>(cur);
switch (subCur->GetType())
{
@@ -239,22 +239,20 @@ otError NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aCon
aConfig.mExternalRoute = nullptr;
aConfig.mService = nullptr;
memset(aConfig.mOnMeshPrefix, 0, sizeof(OnMeshPrefixConfig));
aConfig.mOnMeshPrefix->Clear();
memcpy(&aConfig.mOnMeshPrefix->mPrefix.mPrefix, prefix->GetPrefix(),
BitVectorBytes(prefix->GetPrefixLength()));
aConfig.mOnMeshPrefix->mPrefix.mLength = prefix->GetPrefixLength();
aConfig.mOnMeshPrefix->mPreference = borderRouterEntry->GetPreference();
aConfig.mOnMeshPrefix->mPreferred = borderRouterEntry->IsPreferred();
aConfig.mOnMeshPrefix->mSlaac = borderRouterEntry->IsSlaac();
aConfig.mOnMeshPrefix->mDhcp = borderRouterEntry->IsDhcp();
aConfig.mOnMeshPrefix->mConfigure = borderRouterEntry->IsConfigure();
aConfig.mOnMeshPrefix->mDefaultRoute = borderRouterEntry->IsDefaultRoute();
aConfig.mOnMeshPrefix->mOnMesh = borderRouterEntry->IsOnMesh();
aConfig.mOnMeshPrefix->mStable = borderRouter->IsStable();
aConfig.mOnMeshPrefix->mRloc16 = borderRouterEntry->GetRloc();
aConfig.mOnMeshPrefix->mNdDns = borderRouterEntry->IsNdDns();
aConfig.mOnMeshPrefix->mDp = borderRouterEntry->IsDp();
prefixTlv->CopyPrefixTo(aConfig.mOnMeshPrefix->GetPrefix());
aConfig.mOnMeshPrefix->mPreference = borderRouterEntry->GetPreference();
aConfig.mOnMeshPrefix->mPreferred = borderRouterEntry->IsPreferred();
aConfig.mOnMeshPrefix->mSlaac = borderRouterEntry->IsSlaac();
aConfig.mOnMeshPrefix->mDhcp = borderRouterEntry->IsDhcp();
aConfig.mOnMeshPrefix->mConfigure = borderRouterEntry->IsConfigure();
aConfig.mOnMeshPrefix->mDefaultRoute = borderRouterEntry->IsDefaultRoute();
aConfig.mOnMeshPrefix->mOnMesh = borderRouterEntry->IsOnMesh();
aConfig.mOnMeshPrefix->mStable = borderRouter->IsStable();
aConfig.mOnMeshPrefix->mRloc16 = borderRouterEntry->GetRloc();
aConfig.mOnMeshPrefix->mNdDns = borderRouterEntry->IsNdDns();
aConfig.mOnMeshPrefix->mDp = borderRouterEntry->IsDp();
ExitNow(error = OT_ERROR_NONE);
}
@@ -280,14 +278,12 @@ otError NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aCon
aConfig.mOnMeshPrefix = nullptr;
aConfig.mService = nullptr;
memset(aConfig.mExternalRoute, 0, sizeof(ExternalRouteConfig));
aConfig.mExternalRoute->Clear();
memcpy(&aConfig.mExternalRoute->mPrefix.mPrefix, prefix->GetPrefix(),
BitVectorBytes(prefix->GetPrefixLength()));
aConfig.mExternalRoute->mPrefix.mLength = prefix->GetPrefixLength();
aConfig.mExternalRoute->mPreference = hasRouteEntry->GetPreference();
aConfig.mExternalRoute->mStable = hasRoute->IsStable();
aConfig.mExternalRoute->mRloc16 = hasRouteEntry->GetRloc();
prefixTlv->CopyPrefixTo(aConfig.mExternalRoute->GetPrefix());
aConfig.mExternalRoute->mPreference = hasRouteEntry->GetPreference();
aConfig.mExternalRoute->mStable = hasRoute->IsStable();
aConfig.mExternalRoute->mRloc16 = hasRouteEntry->GetRloc();
aConfig.mExternalRoute->mNextHopIsThisDevice =
(hasRouteEntry->GetRloc() == Get<Mle::MleRouter>().GetRloc16());
@@ -319,7 +315,7 @@ otError NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aCon
{
aConfig.mOnMeshPrefix = nullptr;
aConfig.mExternalRoute = nullptr;
memset(aConfig.mService, 0, sizeof(ServiceConfig));
aConfig.mService->Clear();
aConfig.mService->mServiceId = service->GetServiceId();
aConfig.mService->mEnterpriseNumber = service->GetEnterpriseNumber();
@@ -671,8 +667,7 @@ const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix,
VerifyOrExit(prefixTlv != nullptr, OT_NOOP);
if (prefixTlv->GetPrefixLength() == aPrefixLength &&
PrefixMatch(prefixTlv->GetPrefix(), aPrefix, aPrefixLength) >= aPrefixLength)
if (prefixTlv->IsEqual(aPrefix, aPrefixLength))
{
ExitNow();
}
@@ -686,18 +681,6 @@ exit:
return prefixTlv;
}
int8_t NetworkData::PrefixMatch(const uint8_t *a, const uint8_t *b, uint8_t aLength)
{
uint8_t matchedLength;
// Note that he `Ip6::Address::PrefixMatch` expects the prefix
// length to be in bytes unit.
matchedLength = Ip6::Address::PrefixMatch(a, b, BitVectorBytes(aLength));
return (matchedLength >= aLength) ? static_cast<int8_t>(matchedLength) : -1;
}
const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
const uint8_t *aServiceData,
uint8_t aServiceDataLength) const
+79 -29
View File
@@ -40,6 +40,7 @@
#include <openthread/server.h>
#include "coap/coap.hpp"
#include "common/clearable.hpp"
#include "common/locator.hpp"
#include "common/timer.hpp"
#include "net/udp6.hpp"
@@ -96,22 +97,60 @@ enum
typedef otNetworkDataIterator Iterator;
/**
* This type represents an On Mesh Prefix (Border Router) configuration.
* This class represents an On Mesh Prefix (Border Router) configuration.
*
*/
typedef otBorderRouterConfig OnMeshPrefixConfig;
class OnMeshPrefixConfig : public otBorderRouterConfig, public Clearable<OnMeshPrefixConfig>
{
public:
/**
* This method get the prefix.
*
* @return The prefix.
*
*/
const Ip6::Prefix &GetPrefix(void) const { return static_cast<const Ip6::Prefix &>(mPrefix); }
/**
* This method get the prefix.
*
* @return The prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return static_cast<Ip6::Prefix &>(mPrefix); }
};
/**
* This type represents an External Route configuration.
* This class represents an External Route configuration.
*
*/
typedef otExternalRouteConfig ExternalRouteConfig;
class ExternalRouteConfig : public otExternalRouteConfig, public Clearable<ExternalRouteConfig>
{
public:
/**
* This method get the prefix.
*
* @return The prefix.
*
*/
const Ip6::Prefix &GetPrefix(void) const { return static_cast<const Ip6::Prefix &>(mPrefix); }
/**
* This method get the prefix.
*
* @return The prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return static_cast<Ip6::Prefix &>(mPrefix); }
};
/**
* This type represents a Service configuration.
*
*/
typedef otServiceConfig ServiceConfig;
class ServiceConfig : public otServiceConfig, public Clearable<ServiceConfig>
{
};
/**
* This class implements Network Data processing.
@@ -450,7 +489,7 @@ protected:
*
* @param[in] aPrefix A reference to the Prefix TLV.
*
* @returns A pointer to the Context TLV is one is found or nullptr if no Context TLV exists.
* @returns A pointer to the Context TLV if one is found or nullptr if no Context TLV exists.
*
*/
static ContextTlv *FindContext(PrefixTlv &aPrefix)
@@ -463,7 +502,7 @@ protected:
*
* @param[in] aPrefix A reference to the Prefix TLV.
*
* @returns A pointer to the Context TLV is one is found or nullptr if no Context TLV exists.
* @returns A pointer to the Context TLV if one is found or nullptr if no Context TLV exists.
*
*/
static const ContextTlv *FindContext(const PrefixTlv &aPrefix);
@@ -472,9 +511,9 @@ protected:
* This method returns a pointer to a Prefix TLV.
*
* @param[in] aPrefix A pointer to an IPv6 prefix.
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix.
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
*
* @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
*
*/
PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
@@ -486,13 +525,36 @@ protected:
* This method returns a pointer to a Prefix TLV.
*
* @param[in] aPrefix A pointer to an IPv6 prefix.
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix.
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
*
* @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
*
*/
const PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
/**
* This method returns a pointer to a Prefix TLV.
*
* @param[in] aPrefix An IPv6 prefix.
*
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
*
*/
PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) { return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); }
/**
* This method returns a pointer to a Prefix TLV.
*
* @param[in] aPrefix An IPv6 prefix.
*
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
*
*/
const PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) const
{
return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength());
}
/**
* This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
*
@@ -501,7 +563,7 @@ protected:
* @param[in] aTlvs A pointer to a specified tlvs buffer.
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
*
* @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
*
*/
static PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength)
@@ -518,7 +580,7 @@ protected:
* @param[in] aTlvs A pointer to a specified tlvs buffer.
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
*
* @returns A pointer to the Prefix TLV is one is found or nullptr if no matching Prefix TLV exists.
* @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
*
*/
static const PrefixTlv *FindPrefix(const uint8_t *aPrefix,
@@ -533,7 +595,7 @@ protected:
* @param[in] aServiceData A pointer to a Service Data.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
*
* @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
ServiceTlv *FindService(uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength)
@@ -549,7 +611,7 @@ protected:
* @param[in] aServiceData A pointer to a Service Data.
* @param[in] aServiceDataLength The Service Data length pointed to by @p aServiceData.
*
* @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
const ServiceTlv *FindService(uint32_t aEnterpriseNumber,
@@ -565,7 +627,7 @@ protected:
* @param[in] aTlvs A pointer to a specified tlvs buffer.
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
*
* @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
static ServiceTlv *FindService(uint32_t aEnterpriseNumber,
@@ -587,7 +649,7 @@ protected:
* @param[in] aTlvs A pointer to a specified tlvs buffer.
* @param[in] aTlvsLength The specified tlvs buffer length pointed to by @p aTlvs.
*
* @returns A pointer to the Service TLV is one is found or nullptr if no matching Service TLV exists.
* @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
*
*/
static const ServiceTlv *FindService(uint32_t aEnterpriseNumber,
@@ -658,18 +720,6 @@ protected:
*/
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength);
/**
* This method computes the number of IPv6 Prefix bits that match.
*
* @param[in] a A pointer to the first IPv6 Prefix.
* @param[in] b A pointer to the second IPv6 prefix.
* @param[in] aLength The maximum length in bits to compare.
*
* @returns The number of matching bits.
*
*/
static int8_t PrefixMatch(const uint8_t *a, const uint8_t *b, uint8_t aLength);
/**
* This method sends a Server Data Notification message to the Leader.
*
+46 -47
View File
@@ -73,9 +73,9 @@ otError LeaderBase::GetServiceId(uint32_t aEnterpriseNumber,
bool aServerStable,
uint8_t & aServiceId) const
{
otError error = OT_ERROR_NOT_FOUND;
Iterator iterator = kIteratorInit;
otServiceConfig serviceConfig;
otError error = OT_ERROR_NOT_FOUND;
Iterator iterator = kIteratorInit;
ServiceConfig serviceConfig;
while (GetNextService(iterator, serviceConfig) == OT_ERROR_NONE)
{
@@ -140,19 +140,19 @@ exit:
const PrefixTlv *LeaderBase::FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const
{
const PrefixTlv *prefix;
const PrefixTlv *prefixTlv;
for (const NetworkDataTlv *start = (aPrevTlv == nullptr) ? GetTlvsStart() : aPrevTlv->GetNext();
(prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr; start = prefix->GetNext())
(prefixTlv = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr; start = prefixTlv->GetNext())
{
if (PrefixMatch(prefix->GetPrefix(), aAddress.mFields.m8, prefix->GetPrefixLength()) >= 0)
if (aAddress.MatchesPrefix(prefixTlv->GetPrefix(), prefixTlv->GetPrefixLength()))
{
ExitNow();
}
}
exit:
return prefix;
return prefixTlv;
}
otError LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const
@@ -160,12 +160,11 @@ otError LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aC
const PrefixTlv * prefix = nullptr;
const ContextTlv *contextTlv;
aContext.mPrefixLength = 0;
aContext.mPrefix.SetLength(0);
if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
{
aContext.mPrefix = Get<Mle::MleRouter>().GetMeshLocalPrefix().m8;
aContext.mPrefixLength = Mle::MeshLocalPrefix::kLength;
aContext.mPrefix.Set(Get<Mle::MleRouter>().GetMeshLocalPrefix());
aContext.mContextId = Mle::kMeshLocalPrefixContextId;
aContext.mCompressFlag = true;
}
@@ -179,16 +178,15 @@ otError LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aC
continue;
}
if (prefix->GetPrefixLength() > aContext.mPrefixLength)
if (prefix->GetPrefixLength() > aContext.mPrefix.GetLength())
{
aContext.mPrefix = prefix->GetPrefix();
aContext.mPrefixLength = prefix->GetPrefixLength();
aContext.mPrefix.Set(prefix->GetPrefix(), prefix->GetPrefixLength());
aContext.mContextId = contextTlv->GetContextId();
aContext.mCompressFlag = contextTlv->IsCompress();
}
}
return (aContext.mPrefixLength > 0) ? OT_ERROR_NONE : OT_ERROR_NOT_FOUND;
return (aContext.mPrefix.GetLength() > 0) ? OT_ERROR_NONE : OT_ERROR_NOT_FOUND;
}
otError LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) const
@@ -198,8 +196,7 @@ otError LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) co
if (aContextId == Mle::kMeshLocalPrefixContextId)
{
aContext.mPrefix = Get<Mle::MleRouter>().GetMeshLocalPrefix().m8;
aContext.mPrefixLength = Mle::MeshLocalPrefix::kLength;
aContext.mPrefix.Set(Get<Mle::MleRouter>().GetMeshLocalPrefix());
aContext.mContextId = Mle::kMeshLocalPrefixContextId;
aContext.mCompressFlag = true;
ExitNow(error = OT_ERROR_NONE);
@@ -215,8 +212,7 @@ otError LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) co
continue;
}
aContext.mPrefix = prefix->GetPrefix();
aContext.mPrefixLength = prefix->GetPrefixLength();
aContext.mPrefix.Set(prefix->GetPrefix(), prefix->GetPrefixLength());
aContext.mContextId = contextTlv->GetContextId();
aContext.mCompressFlag = contextTlv->IsCompress();
ExitNow(error = OT_ERROR_NONE);
@@ -238,8 +234,7 @@ otError LeaderBase::GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16) co
while (GetNextOnMeshPrefix(iterator, config) == OT_ERROR_NONE)
{
if (otIp6PrefixMatch(&(config.mPrefix.mPrefix), reinterpret_cast<const otIp6Address *>(
lowpanContext.mPrefix)) >= config.mPrefix.mLength)
if (lowpanContext.mPrefix.ContainsPrefix(config.GetPrefix()))
{
aRloc16 = config.mRloc16;
ExitNow(error = OT_ERROR_NONE);
@@ -287,7 +282,7 @@ exit:
otError LeaderBase::RouteLookup(const Ip6::Address &aSource,
const Ip6::Address &aDestination,
uint8_t * aPrefixMatch,
uint8_t * aPrefixMatchLength,
uint16_t * aRloc16) const
{
otError error = OT_ERROR_NO_ROUTE;
@@ -295,16 +290,16 @@ otError LeaderBase::RouteLookup(const Ip6::Address &aSource,
while ((prefix = FindNextMatchingPrefix(aSource, prefix)) != nullptr)
{
if (ExternalRouteLookup(prefix->GetDomainId(), aDestination, aPrefixMatch, aRloc16) == OT_ERROR_NONE)
if (ExternalRouteLookup(prefix->GetDomainId(), aDestination, aPrefixMatchLength, aRloc16) == OT_ERROR_NONE)
{
ExitNow(error = OT_ERROR_NONE);
}
if (DefaultRouteLookup(*prefix, aRloc16) == OT_ERROR_NONE)
{
if (aPrefixMatch)
if (aPrefixMatchLength)
{
*aPrefixMatch = 0;
*aPrefixMatchLength = 0;
}
ExitNow(error = OT_ERROR_NONE);
@@ -317,62 +312,66 @@ exit:
otError LeaderBase::ExternalRouteLookup(uint8_t aDomainId,
const Ip6::Address &aDestination,
uint8_t * aPrefixMatch,
uint8_t * aPrefixMatchLength,
uint16_t * aRloc16) const
{
otError error = OT_ERROR_NO_ROUTE;
const PrefixTlv * prefix;
const HasRouteEntry *rvalRoute = nullptr;
uint8_t rval_plen = 0;
const PrefixTlv * prefixTlv;
const HasRouteEntry *bestRouteEntry = nullptr;
uint8_t bestMatchLength = 0;
for (const NetworkDataTlv *start = GetTlvsStart(); (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
start = prefix->GetNext())
for (const NetworkDataTlv *start = GetTlvsStart(); (prefixTlv = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
start = prefixTlv->GetNext())
{
const HasRouteTlv *hasRoute;
int8_t plen;
uint8_t prefixLength = prefixTlv->GetPrefixLength();
if (prefix->GetDomainId() != aDomainId)
if (prefixTlv->GetDomainId() != aDomainId)
{
continue;
}
plen = PrefixMatch(prefix->GetPrefix(), aDestination.mFields.m8, prefix->GetPrefixLength());
if (plen <= rval_plen)
if (!aDestination.MatchesPrefix(prefixTlv->GetPrefix(), prefixLength))
{
continue;
}
for (const NetworkDataTlv *subStart = prefix->GetSubTlvs();
(hasRoute = FindTlv<HasRouteTlv>(subStart, prefix->GetNext())) != nullptr; subStart = hasRoute->GetNext())
if (prefixLength <= bestMatchLength)
{
continue;
}
for (const NetworkDataTlv *subStart = prefixTlv->GetSubTlvs();
(hasRoute = FindTlv<HasRouteTlv>(subStart, prefixTlv->GetNext())) != nullptr;
subStart = hasRoute->GetNext())
{
for (const HasRouteEntry *entry = hasRoute->GetFirstEntry(); entry <= hasRoute->GetLastEntry();
entry = entry->GetNext())
{
if (rvalRoute == nullptr || entry->GetPreference() > rvalRoute->GetPreference() ||
(entry->GetPreference() == rvalRoute->GetPreference() &&
if (bestRouteEntry == nullptr || entry->GetPreference() > bestRouteEntry->GetPreference() ||
(entry->GetPreference() == bestRouteEntry->GetPreference() &&
(entry->GetRloc() == Get<Mle::MleRouter>().GetRloc16() ||
(rvalRoute->GetRloc() != Get<Mle::MleRouter>().GetRloc16() &&
(bestRouteEntry->GetRloc() != Get<Mle::MleRouter>().GetRloc16() &&
Get<Mle::MleRouter>().GetCost(entry->GetRloc()) <
Get<Mle::MleRouter>().GetCost(rvalRoute->GetRloc())))))
Get<Mle::MleRouter>().GetCost(bestRouteEntry->GetRloc())))))
{
rvalRoute = entry;
rval_plen = static_cast<uint8_t>(plen);
bestRouteEntry = entry;
bestMatchLength = prefixLength;
}
}
}
}
if (rvalRoute != nullptr)
if (bestRouteEntry != nullptr)
{
if (aRloc16 != nullptr)
{
*aRloc16 = rvalRoute->GetRloc();
*aRloc16 = bestRouteEntry->GetRloc();
}
if (aPrefixMatch != nullptr)
if (aPrefixMatchLength != nullptr)
{
*aPrefixMatch = rval_plen;
*aPrefixMatchLength = bestMatchLength;
}
error = OT_ERROR_NONE;
+6 -6
View File
@@ -137,10 +137,10 @@ public:
/**
* This method performs a route lookup using the Network Data.
*
* @param[in] aSource A reference to the IPv6 source address.
* @param[in] aDestination A reference to the IPv6 destination address.
* @param[out] aPrefixMatch A pointer to the longest prefix match length in bits.
* @param[out] aRloc16 A pointer to the RLOC16 for the selected route.
* @param[in] aSource A reference to the IPv6 source address.
* @param[in] aDestination A reference to the IPv6 destination address.
* @param[out] aPrefixMatchLength A pointer to output the longest prefix match length in bits.
* @param[out] aRloc16 A pointer to the RLOC16 for the selected route.
*
* @retval OT_ERROR_NONE Successfully found a route.
* @retval OT_ERROR_NO_ROUTE No valid route was found.
@@ -148,7 +148,7 @@ public:
*/
otError RouteLookup(const Ip6::Address &aSource,
const Ip6::Address &aDestination,
uint8_t * aPrefixMatch,
uint8_t * aPrefixMatchLength,
uint16_t * aRloc16) const;
/**
@@ -300,7 +300,7 @@ private:
otError ExternalRouteLookup(uint8_t aDomainId,
const Ip6::Address &aDestination,
uint8_t * aPrefixMatch,
uint8_t * aPrefixMatchLength,
uint16_t * aRloc16) const;
otError DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const;
};
+20 -23
View File
@@ -100,38 +100,37 @@ otError Local::AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig)
}
#endif
return AddPrefix(aConfig.mPrefix.mPrefix.mFields.m8, aConfig.mPrefix.mLength, NetworkDataTlv::kTypeBorderRouter,
aConfig.mPreference, flags, aConfig.mStable);
return AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeBorderRouter, aConfig.mPreference, flags,
aConfig.mStable);
}
otError Local::RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
otError Local::RemoveOnMeshPrefix(const Ip6::Prefix &aPrefix)
{
return RemovePrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeBorderRouter);
return RemovePrefix(aPrefix, NetworkDataTlv::kTypeBorderRouter);
}
otError Local::AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, bool aStable)
otError Local::AddHasRoutePrefix(const ExternalRouteConfig &aConfig)
{
return AddPrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeHasRoute, aPrf, /* aFlags */ 0, aStable);
return AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeHasRoute, aConfig.mPreference, /* aFlags */ 0,
aConfig.mStable);
}
otError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
otError Local::RemoveHasRoutePrefix(const Ip6::Prefix &aPrefix)
{
return RemovePrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeHasRoute);
return RemovePrefix(aPrefix, NetworkDataTlv::kTypeHasRoute);
}
otError Local::AddPrefix(const uint8_t * aPrefix,
uint8_t aPrefixLength,
otError Local::AddPrefix(const Ip6::Prefix & aPrefix,
NetworkDataTlv::Type aSubTlvType,
int8_t aPrf,
uint16_t aFlags,
bool aStable)
{
otError error = OT_ERROR_NONE;
uint8_t prefixLengthBytes = BitVectorBytes(aPrefixLength);
otError error = OT_ERROR_NONE;
uint8_t subTlvLength;
PrefixTlv *prefixTlv;
VerifyOrExit(aPrefixLength > 0 && prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS);
VerifyOrExit((aPrefix.GetLength() > 0) && aPrefix.IsValid(), error = OT_ERROR_INVALID_ARGS);
switch (aPrf)
{
@@ -143,20 +142,18 @@ otError Local::AddPrefix(const uint8_t * aPrefix,
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, Get<Mle::MleRouter>().GetMeshLocalPrefix().m8, prefixLengthBytes) <
Mle::MeshLocalPrefix::kLength,
error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(!aPrefix.ContainsPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix()), error = OT_ERROR_INVALID_ARGS);
IgnoreError(RemovePrefix(aPrefix, aPrefixLength, aSubTlvType));
IgnoreError(RemovePrefix(aPrefix, aSubTlvType));
subTlvLength = (aSubTlvType == NetworkDataTlv::kTypeBorderRouter)
? sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry)
: sizeof(HasRouteTlv) + sizeof(HasRouteEntry);
prefixTlv = static_cast<PrefixTlv *>(AppendTlv(sizeof(PrefixTlv) + prefixLengthBytes + subTlvLength));
prefixTlv = static_cast<PrefixTlv *>(AppendTlv(sizeof(PrefixTlv) + aPrefix.GetBytesSize() + subTlvLength));
VerifyOrExit(prefixTlv != nullptr, error = OT_ERROR_NO_BUFS);
prefixTlv->Init(0, aPrefixLength, aPrefix);
prefixTlv->Init(0, aPrefix);
prefixTlv->SetSubTlvsLength(subTlvLength);
if (aSubTlvType == NetworkDataTlv::kTypeBorderRouter)
@@ -189,12 +186,12 @@ exit:
return error;
}
otError Local::RemovePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, NetworkDataTlv::Type aSubTlvType)
otError Local::RemovePrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubTlvType)
{
otError error = OT_ERROR_NONE;
PrefixTlv *tlv;
VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != nullptr, error = OT_ERROR_NOT_FOUND);
VerifyOrExit((tlv = FindPrefix(aPrefix)) != nullptr, error = OT_ERROR_NOT_FOUND);
VerifyOrExit(FindTlv(tlv->GetSubTlvs(), tlv->GetNext(), aSubTlvType) != nullptr, error = OT_ERROR_NOT_FOUND);
RemoveTlv(tlv);
@@ -203,11 +200,11 @@ exit:
return error;
}
void Local::UpdateRloc(PrefixTlv &aPrefix)
void Local::UpdateRloc(PrefixTlv &aPrefixTlv)
{
uint16_t rloc16 = Get<Mle::MleRouter>().GetRloc16();
for (NetworkDataTlv *cur = aPrefix.GetSubTlvs(); cur < aPrefix.GetNext(); cur = cur->GetNext())
for (NetworkDataTlv *cur = aPrefixTlv.GetSubTlvs(); cur < aPrefixTlv.GetNext(); cur = cur->GetNext())
{
switch (cur->GetType())
{
+9 -15
View File
@@ -85,40 +85,35 @@ public:
/**
* This method removes a Border Router entry from the Thread Network Data.
*
* @param[in] aPrefix A pointer to the prefix.
* @param[in] aPrefixLength The prefix length in bits.
* @param[in] aPrefix The Prefix to remove.
*
* @retval OT_ERROR_NONE Successfully removed the Border Router entry.
* @retval OT_ERROR_NOT_FOUND Could not find the Border Router entry.
*
*/
otError RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
otError RemoveOnMeshPrefix(const Ip6::Prefix &aPrefix);
/**
* This method adds a Has Route entry to the Thread Network data.
*
* @param[in] aPrefix A pointer to the prefix.
* @param[in] aPrefixLength The prefix length in bits.
* @param[in] aPrf The preference value.
* @param[in] aStable The Stable value.
* @param[in] aConfig A reference to the external route configuration.
*
* @retval OT_ERROR_NONE Successfully added the Has Route entry.
* @retval OT_ERROR_NO_BUFS Insufficient space to add the Has Route entry.
*
*/
otError AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, bool aStable);
otError AddHasRoutePrefix(const ExternalRouteConfig &aConfig);
/**
* This method removes a Border Router entry from the Thread Network Data.
*
* @param[in] aPrefix A pointer to the prefix.
* @param[in] aPrefixLength The prefix length in bits.
* @param[in] aPrefix The Prefix to remove.
*
* @retval OT_ERROR_NONE Successfully removed the Border Router entry.
* @retval OT_ERROR_NOT_FOUND Could not find the Border Router entry.
*
*/
otError RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength);
otError RemoveHasRoutePrefix(const Ip6::Prefix &aPrefix);
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
@@ -174,14 +169,13 @@ public:
private:
void UpdateRloc(void);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
otError AddPrefix(const uint8_t * aPrefix,
uint8_t aPrefixLength,
otError AddPrefix(const Ip6::Prefix & aPrefix,
NetworkDataTlv::Type aSubTlvType,
int8_t aPrf,
uint16_t aFlags,
bool aStable);
otError RemovePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, NetworkDataTlv::Type aSubTlvType);
void UpdateRloc(PrefixTlv &aPrefix);
otError RemovePrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubTlvType);
void UpdateRloc(PrefixTlv &aPrefixTlv);
bool IsOnMeshPrefixConsistent(void) const;
bool IsExternalRouteConsistent(void) const;
#endif
+59 -8
View File
@@ -429,10 +429,22 @@ public:
SetType(kTypePrefix);
mDomainId = aDomainId;
mPrefixLength = aPrefixLength;
memcpy(GetPrefix(), aPrefix, BitVectorBytes(aPrefixLength));
memcpy(GetPrefix(), aPrefix, Ip6::Prefix::SizeForLength(aPrefixLength));
SetSubTlvsLength(0);
}
/**
* This method initializes the TLV.
*
* @param[in] aDomainId The Domain ID.
* @param[in] aPrefix The Prefix.
*
*/
void Init(uint8_t aDomainId, const Ip6::Prefix aPrefix)
{
Init(aDomainId, aPrefix.GetLength(), aPrefix.GetBytes());
}
/**
* This method indicates whether or not the TLV appears to be well-formed.
*
@@ -443,8 +455,8 @@ public:
bool IsValid(void) const
{
return ((GetLength() >= sizeof(*this) - sizeof(NetworkDataTlv)) &&
(GetLength() >= BitVectorBytes(mPrefixLength) + sizeof(*this) - sizeof(NetworkDataTlv)) &&
(BitVectorBytes(mPrefixLength) <= sizeof(Ip6::Address)));
(GetLength() >= Ip6::Prefix::SizeForLength(mPrefixLength) + sizeof(*this) - sizeof(NetworkDataTlv)) &&
(Ip6::Prefix::SizeForLength(mPrefixLength) <= sizeof(Ip6::Address)));
}
/**
@@ -479,6 +491,42 @@ public:
*/
const uint8_t *GetPrefix(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
/**
* This method copies the Prefix from TLV into a given `Ip6::Prefix`.
*
* @param[out] aPrefix An `Ip6::Prefix` to copy the Prefix from TLV into.
*
*/
void CopyPrefixTo(Ip6::Prefix &aPrefix) const { aPrefix.Set(GetPrefix(), GetPrefixLength()); }
/**
* This method indicates whether the Prefix from TLV is equal to a given `Ip6::Prefix`.
*
* @param[in] aPrefix A Prefix to compare with.
*
* @retval TRUE The TLV's Prefix is equal to @p aPrefix.
* @retval FALSE The TLV's Prefix is not equal to @p aPrefix.
*
*/
bool IsEqual(Ip6::Prefix &aPrefix) const { return aPrefix.IsEqual(GetPrefix(), GetPrefixLength()); }
/**
* This method indicates whether the Prefix from TLV is equal to a given Prefix.
*
* @param[in] aPrefix A pointer to an IPv6 prefix to compare with.
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
*
* @retval TRUE The TLV's Prefix is equal to @p aPrefix.
* @retval FALSE The TLV's Prefix is not euqal @p aPrefix.
*
*/
bool IsEqual(const uint8_t *aPrefix, uint8_t aPrefixLength) const
{
return (aPrefixLength == mPrefixLength) &&
(Ip6::Prefix::MatchLength(GetPrefix(), aPrefix, Ip6::Prefix::SizeForLength(aPrefixLength)) >=
mPrefixLength);
}
/**
* This method returns a pointer to the Sub-TLVs.
*
@@ -487,7 +535,7 @@ public:
*/
NetworkDataTlv *GetSubTlvs(void)
{
return reinterpret_cast<NetworkDataTlv *>(GetPrefix() + BitVectorBytes(mPrefixLength));
return reinterpret_cast<NetworkDataTlv *>(GetPrefix() + Ip6::Prefix::SizeForLength(mPrefixLength));
}
/**
@@ -498,7 +546,7 @@ public:
*/
const NetworkDataTlv *GetSubTlvs(void) const
{
return reinterpret_cast<const NetworkDataTlv *>(GetPrefix() + BitVectorBytes(mPrefixLength));
return reinterpret_cast<const NetworkDataTlv *>(GetPrefix() + Ip6::Prefix::SizeForLength(mPrefixLength));
}
/**
@@ -509,7 +557,7 @@ public:
*/
uint8_t GetSubTlvsLength(void) const
{
return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv) + BitVectorBytes(mPrefixLength));
return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv) + Ip6::Prefix::SizeForLength(mPrefixLength));
}
/**
@@ -520,7 +568,7 @@ public:
*/
void SetSubTlvsLength(uint8_t aLength)
{
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + BitVectorBytes(mPrefixLength) + aLength);
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + Ip6::Prefix::SizeForLength(mPrefixLength) + aLength);
}
/**
@@ -534,7 +582,10 @@ public:
* @returns The size (number of bytes) of the Prefix TLV.
*
*/
static uint16_t CalculateSize(uint8_t aPrefixLength) { return sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength); }
static uint16_t CalculateSize(uint8_t aPrefixLength)
{
return sizeof(PrefixTlv) + Ip6::Prefix::SizeForLength(aPrefixLength);
}
private:
uint8_t mDomainId;
+6 -5
View File
@@ -94,7 +94,7 @@ exit:
return;
}
bool Slaac::ShouldFilter(const otIp6Prefix &aPrefix) const
bool Slaac::ShouldFilter(const Ip6::Prefix &aPrefix) const
{
return (mFilter != nullptr) && mFilter(&GetInstance(), &aPrefix);
}
@@ -143,7 +143,7 @@ bool Slaac::DoesConfigMatchNetifAddr(const NetworkData::OnMeshPrefixConfig &aCon
{
return (((aConfig.mOnMesh && (aAddr.mPrefixLength == aConfig.mPrefix.mLength)) ||
(!aConfig.mOnMesh && (aAddr.mPrefixLength == 128))) &&
(aAddr.GetAddress().PrefixMatch(aConfig.mPrefix.mPrefix) >= aConfig.mPrefix.mLength));
(aAddr.GetAddress().MatchesPrefix(aConfig.GetPrefix())));
}
void Slaac::Update(UpdateMode aMode)
@@ -179,7 +179,8 @@ void Slaac::Update(UpdateMode aMode)
continue;
}
if (config.mSlaac && !ShouldFilter(config.mPrefix) && DoesConfigMatchNetifAddr(config, *slaacAddr))
if (config.mSlaac && !ShouldFilter(config.GetPrefix()) &&
DoesConfigMatchNetifAddr(config, *slaacAddr))
{
found = true;
break;
@@ -205,7 +206,7 @@ void Slaac::Update(UpdateMode aMode)
while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, config) == OT_ERROR_NONE)
{
otIp6Prefix &prefix = config.mPrefix;
Ip6::Prefix &prefix = config.GetPrefix();
if (config.mDp || !config.mSlaac || ShouldFilter(prefix))
{
@@ -236,7 +237,7 @@ void Slaac::Update(UpdateMode aMode)
}
slaacAddr->Clear();
memcpy(&slaacAddr->mAddress, &prefix.mPrefix, BitVectorBytes(prefix.mLength));
slaacAddr->GetAddress().SetPrefix(prefix);
slaacAddr->mPrefixLength = config.mOnMesh ? prefix.mLength : 128;
slaacAddr->mAddressOrigin = OT_ADDRESS_ORIGIN_SLAAC;
+1 -1
View File
@@ -159,7 +159,7 @@ private:
typedef uint8_t UpdateMode;
bool ShouldFilter(const otIp6Prefix &aPrefix) const;
bool ShouldFilter(const Ip6::Prefix &aPrefix) const;
void Update(UpdateMode aMode);
void GetIidSecretKey(IidSecretKey &aKey) const;
static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
+58
View File
@@ -217,10 +217,68 @@ void TestIp6AddressSetPrefix(void)
}
}
void TestIp6Prefix(void)
{
const uint8_t kPrefixes[][OT_IP6_ADDRESS_SIZE] = {
{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
};
ot::Ip6::Prefix prefix;
ot::Ip6::Address address1, address2;
for (auto prefixBytes : kPrefixes)
{
memcpy(address1.mFields.m8, prefixBytes, sizeof(address1));
address2 = address1;
address2.mFields.m8[0] ^= 0x80; // Change first bit.
for (uint8_t prefixLength = 1; prefixLength <= ot::Ip6::Prefix::kMaxLength; prefixLength++)
{
prefix.Set(prefixBytes, prefixLength);
printf("Prefix %s\n", prefix.ToString().AsCString());
VerifyOrQuit(prefix.GetLength() == prefixLength, "Prefix::GetLength() failed");
VerifyOrQuit(prefix.IsValid(), "Prefix::IsValid() failed");
VerifyOrQuit(prefix.IsEqual(prefixBytes, prefixLength), "Prefix::IsEqual() failed");
VerifyOrQuit(address1.MatchesPrefix(prefix), "Address::MatchesPrefix() failed");
VerifyOrQuit(!address2.MatchesPrefix(prefix), "Address::MatchedPrefix() failed");
VerifyOrQuit(prefix == prefix, "Prefix::operator==() failed");
for (uint8_t subPrefixLength = 1; subPrefixLength <= prefixLength; subPrefixLength++)
{
ot::Ip6::Prefix subPrefix;
subPrefix.Set(prefixBytes, subPrefixLength);
VerifyOrQuit(prefix.ContainsPrefix(subPrefix), "Prefix::ContainsPrefix() failed");
if (prefixLength == subPrefixLength)
{
VerifyOrQuit(prefix == subPrefix, "Prefix::operator==() failed");
VerifyOrQuit(prefix.IsEqual(subPrefix.GetBytes(), subPrefix.GetLength()),
"Prefix::IsEqual() failed");
}
else
{
VerifyOrQuit(prefix != subPrefix, "Prefix::operator!= failed");
VerifyOrQuit(!prefix.IsEqual(subPrefix.GetBytes(), subPrefix.GetLength()),
"Prefix::IsEqual() failed");
}
}
}
}
}
int main(void)
{
TestIp6AddressSetPrefix();
TestIp6AddressFromString();
TestIp6Prefix();
printf("All tests passed\n");
return 0;
}
+3 -3
View File
@@ -63,7 +63,7 @@ void PrintExternalRouteConfig(const ExternalRouteConfig &aConfig)
}
// Returns true if the two given ExternalRouteConfig match (intentionally ignoring mNextHopIsThisDevice).
bool CompareExternalRouteConfig(const ExternalRouteConfig &aConfig1, const ExternalRouteConfig &aConfig2)
bool CompareExternalRouteConfig(const otExternalRouteConfig &aConfig1, const otExternalRouteConfig &aConfig2)
{
return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8,
sizeof(aConfig1.mPrefix.mPrefix)) == 0) &&
@@ -85,7 +85,7 @@ void TestNetworkDataIterator(void)
0xFD, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0xC8, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00};
ExternalRouteConfig routes[] = {
otExternalRouteConfig routes[] = {
{
{{{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
64},
@@ -126,7 +126,7 @@ void TestNetworkDataIterator(void)
0x31, 0x00, 0x02, 0x0F, 0x00, 0x40, 0xFD, 0x00, 0xAB, 0xBA, 0xCD, 0xDC, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00,
0x00, 0x03, 0x0E, 0x00, 0x20, 0xFD, 0x00, 0xAB, 0xBA, 0x01, 0x06, 0x54, 0x00, 0x00, 0x04, 0x00, 0x00};
ExternalRouteConfig routes[] = {
otExternalRouteConfig routes[] = {
{{{{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, 64},
0x1000,
1,