[dataset] introduce AffectsConnectivity() and public API (#13134)

This commit introduces helper methods to `MeshCoP::Dataset` to determine
if a given Dataset affects network connectivity or the Network Key.
It also adds a corresponding public API `otDatasetAffectsConnectivity()`.

A Dataset is considered to affect connectivity if it contains a
different Channel, PAN ID, Mesh Local Prefix, or Network Key than
the current values in use.
This commit is contained in:
Abtin Keshavarzian
2026-05-27 12:48:31 -07:00
committed by GitHub
parent 597ca44261
commit 3243bc3529
6 changed files with 116 additions and 40 deletions
+18
View File
@@ -633,6 +633,24 @@ void otDatasetConvertToTlvs(const otOperationalDataset *aDataset, otOperationalD
*/ */
otError otDatasetUpdateTlvs(const otOperationalDataset *aDataset, otOperationalDatasetTlvs *aDatasetTlvs); otError otDatasetUpdateTlvs(const otOperationalDataset *aDataset, otOperationalDatasetTlvs *aDatasetTlvs);
/**
* Indicates whether or not a given Operational Dataset (in TLVs format) affects connectivity.
*
* A Dataset affects connectivity if it contains a different Channel, PAN ID, Mesh Local Prefix, Network Key, or
* Security Policy than the current values in use.
*
* The following security policy changes are considered to affect connectivity:
* - Disabling routers (R bit: 1 to 0).
* - Enabling non-CCM routers (NCR bit: 0 to 1).
* - Increasing the version threshold for routing (VR field).
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aDatasetTlvs A pointer to Operational Dataset TLVs.
*
* @returns TRUE if @p aDatasetTlvs affects connectivity, FALSE otherwise.
*/
bool otDatasetAffectsConnectivity(otInstance *aInstance, const otOperationalDatasetTlvs *aDatasetTlvs);
/** /**
* @} * @}
*/ */
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
* *
* @note This number versions both OpenThread platform and user APIs. * @note This number versions both OpenThread platform and user APIs.
*/ */
#define OPENTHREAD_API_VERSION (598) #define OPENTHREAD_API_VERSION (599)
/** /**
* @addtogroup api-instance * @addtogroup api-instance
+14
View File
@@ -228,3 +228,17 @@ otError otDatasetUpdateTlvs(const otOperationalDataset *aDataset, otOperationalD
exit: exit:
return error; return error;
} }
bool otDatasetAffectsConnectivity(otInstance *aInstance, const otOperationalDatasetTlvs *aDatasetTlvs)
{
bool affects = false;
MeshCoP::Dataset dataset;
AssertPointerIsNotNull(aDatasetTlvs);
SuccessOrExit(dataset.SetFrom(*aDatasetTlvs));
affects = dataset.AffectsConnectivity(AsCoreType(aInstance));
exit:
return affects;
}
+45
View File
@@ -611,6 +611,51 @@ exit:
return isSubset; return isSubset;
} }
bool Dataset::AffectsConnectivity(Instance &aInstance) const
{
bool affects = true;
ChannelTlvValue channelValue;
Mac::PanId panId;
Ip6::NetworkPrefix meshLocalPrefix;
if (Read<ChannelTlv>(channelValue) == kErrorNone)
{
VerifyOrExit(channelValue.GetChannel() == aInstance.Get<Mac::Mac>().GetPanChannel());
}
if (Read<PanIdTlv>(panId) == kErrorNone)
{
VerifyOrExit(panId == aInstance.Get<Mac::Mac>().GetPanId());
}
if (Read<MeshLocalPrefixTlv>(meshLocalPrefix) == kErrorNone)
{
VerifyOrExit(meshLocalPrefix == aInstance.Get<Mle::Mle>().GetMeshLocalPrefix());
}
VerifyOrExit(!AffectsNetworkKey(aInstance));
affects = false;
exit:
return affects;
}
bool Dataset::AffectsNetworkKey(Instance &aInstance) const
{
bool affects = false;
NetworkKey networkKey;
NetworkKey localNetworkKey;
SuccessOrExit(Read<NetworkKeyTlv>(networkKey));
aInstance.Get<KeyManager>().GetNetworkKey(localNetworkKey);
affects = (networkKey != localNetworkKey);
exit:
return affects;
}
const char *Dataset::TypeToString(Type aType) { return (aType == kActive) ? "Active" : "Pending"; } const char *Dataset::TypeToString(Type aType) { return (aType == kActive) ? "Active" : "Pending"; }
} // namespace MeshCoP } // namespace MeshCoP
+30
View File
@@ -655,6 +655,36 @@ public:
*/ */
bool IsSubsetOf(const Dataset &aOther) const; bool IsSubsetOf(const Dataset &aOther) const;
/**
* Indicates whether or not the Dataset affects connectivity.
*
* A Dataset affects connectivity if it contains a different Channel, PAN ID, Mesh Local Prefix, Network Key, or
* Security Policy than the current values in use.
*
* The following security policy changes are considered to affect connectivity:
* - Disabling routers (R bit: 1 to 0).
* - Enabling non-CCM routers (NCR bit: 0 to 1).
* - Increasing the version threshold for routing (VR field).
*
* @param[in] aInstance The OpenThread instance.
*
* @retval TRUE The Dataset affects connectivity.
* @retval FALSE The Dataset does not affect connectivity.
*/
bool AffectsConnectivity(Instance &aInstance) const;
/**
* Indicates whether or not the Dataset affects the Network Key.
*
* A Dataset affects the Network Key if it contains a different Network Key than the current value in use.
*
* @param[in] aInstance The OpenThread instance.
*
* @retval TRUE The Dataset affects the Network Key.
* @retval FALSE The Dataset does not affect the Network Key.
*/
bool AffectsNetworkKey(Instance &aInstance) const;
/** /**
* Converts a Dataset Type to a string. * Converts a Dataset Type to a string.
* *
+8 -39
View File
@@ -49,16 +49,12 @@ Error DatasetManager::ProcessSetOrReplaceRequest(MgmtCommand aCommand,
const Coap::Message &aMessage, const Coap::Message &aMessage,
RequestInfo &aInfo) const RequestInfo &aInfo) const
{ {
Error error = kErrorParse; Error error = kErrorParse;
Dataset dataset; Dataset dataset;
OffsetRange offsetRange; OffsetRange offsetRange;
Timestamp activeTimestamp; Timestamp activeTimestamp;
ChannelTlvValue channelValue; uint16_t sessionId;
uint16_t sessionId; uint32_t delayTimer;
Ip6::NetworkPrefix meshLocalPrefix;
NetworkKey networkKey;
uint16_t panId;
uint32_t delayTimer;
aInfo.Clear(); aInfo.Clear();
@@ -86,35 +82,8 @@ Error DatasetManager::ProcessSetOrReplaceRequest(MgmtCommand aCommand,
// Determine whether the new Dataset affects connectivity // Determine whether the new Dataset affects connectivity
// or network key. // or network key.
if ((dataset.Read<ChannelTlv>(channelValue) == kErrorNone) && aInfo.mAffectsConnectivity = dataset.AffectsConnectivity(GetInstance());
(channelValue.GetChannel() != Get<Mac::Mac>().GetPanChannel())) aInfo.mAffectsNetworkKey = dataset.AffectsNetworkKey(GetInstance());
{
aInfo.mAffectsConnectivity = true;
}
if ((dataset.Read<PanIdTlv>(panId) == kErrorNone) && (panId != Get<Mac::Mac>().GetPanId()))
{
aInfo.mAffectsConnectivity = true;
}
if ((dataset.Read<MeshLocalPrefixTlv>(meshLocalPrefix) == kErrorNone) &&
(meshLocalPrefix != Get<Mle::Mle>().GetMeshLocalPrefix()))
{
aInfo.mAffectsConnectivity = true;
}
if (dataset.Read<NetworkKeyTlv>(networkKey) == kErrorNone)
{
NetworkKey localNetworkKey;
Get<KeyManager>().GetNetworkKey(localNetworkKey);
if (networkKey != localNetworkKey)
{
aInfo.mAffectsConnectivity = true;
aInfo.mAffectsNetworkKey = true;
}
}
// Check active timestamp rollback. If there is no change to // Check active timestamp rollback. If there is no change to
// network key, active timestamp must be ahead of local value. // network key, active timestamp must be ahead of local value.