mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 23:57:47 +00:00
[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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user