[bbr] support domain prefix addition and removal (#4793)

This commit is contained in:
Rongli Sun
2020-04-11 22:05:04 -07:00
committed by GitHub
parent a47ea011b1
commit 52777fb459
17 changed files with 453 additions and 201 deletions
+13
View File
@@ -39,6 +39,7 @@
#include <openthread/backbone_router.h>
#include <openthread/ip6.h>
#include <openthread/netdata.h>
#ifdef __cplusplus
extern "C" {
@@ -158,6 +159,18 @@ uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance);
*/
void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter);
/**
* This method gets the local Domain Prefix configuration.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[out] aConfig A pointer to the Domain Prefix configuration.
*
* @retval OT_ERROR_NONE Successfully got the Domain Prefix configuration.
* @retval OT_ERROR_NOT_FOUND No Domain Prefix was configured.
*
*/
otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig);
/**
* @}
*
+12
View File
@@ -102,6 +102,18 @@ typedef struct otBorderRouterConfig
*/
bool mStable : 1;
/**
* TRUE, if this border router is able to supply DNS infomration obtained via ND. FALSE, otherwise.
*/
bool mNdDns : 1;
/**
* TRUE, if this prefix is a Thread Domain Prefix. FALSE, otherwise.
*
* Note: Domain Prefix is introduced since Thread 1.2.
*/
bool mDp : 1;
/**
* The Border Agent Rloc.
*/
+13 -2
View File
@@ -78,7 +78,7 @@ Done
* [ping](#ping-ipaddr-size-count-interval-hoplimit)
* [pollperiod](#pollperiod-pollperiod)
* [preferrouterid](#preferrouterid-routerid)
* [prefix](#prefix-add-prefix-pvdcsr-prf)
* [prefix](#prefix-add-prefix-padcrosnD-prf)
* [promiscuous](#promiscuous)
* [pskc](#pskc--p-keypassphrase)
* [releaserouterid](#releaserouterid-routerid)
@@ -1193,17 +1193,23 @@ Done
### prefix
Get the prefix list in the local Network Data.
Note: For the Thread 1.2 border router with backbone capability, the local Domain
Prefix would be listed as well (with flag `D`), with preceeding `- ` if backbone
functionality is disabled.
```bash
> prefix
2001:dead:beef:cafe::/64 paros med
- fd00:7d03:7d03:7d03::/64 prosD med
Done
```
### prefix add \<prefix\> [pvdcsr] [prf]
### prefix add \<prefix\> [padcrosnD] [prf]
Add a valid prefix to the Network Data.
Note: The Domain Prefix flag (`D`) is only available for Thread 1.2.
* p: Preferred flag
* a: Stateless IPv6 Address Autoconfiguration flag
* d: DHCPv6 IPv6 Address Configuration flag
@@ -1211,11 +1217,16 @@ Add a valid prefix to the Network Data.
* r: Default Route flag
* o: On Mesh flag
* s: Stable flag
* n: Nd Dns flag
* D: Domain Prefix flag
* prf: Default router preference, which may be 'high', 'med', or 'low'.
```bash
> prefix add 2001:dead:beef:cafe::/64 paros med
Done
> prefix add fd00:7d03:7d03:7d03::/64 prosD med
Done
```
### prefix remove \<prefix\>
+91 -54
View File
@@ -2527,6 +2527,15 @@ otError Interpreter::ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[])
config.mStable = true;
break;
case 'n':
config.mNdDns = true;
break;
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
case 'D':
config.mDp = true;
break;
#endif
default:
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
@@ -2575,6 +2584,76 @@ exit:
return error;
}
void Interpreter::OutputPrefix(otBorderRouterConfig &aConfig)
{
mServer->OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[0]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[1]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[2]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[3]), aConfig.mPrefix.mLength);
if (aConfig.mPreferred)
{
mServer->OutputFormat("p");
}
if (aConfig.mSlaac)
{
mServer->OutputFormat("a");
}
if (aConfig.mDhcp)
{
mServer->OutputFormat("d");
}
if (aConfig.mConfigure)
{
mServer->OutputFormat("c");
}
if (aConfig.mDefaultRoute)
{
mServer->OutputFormat("r");
}
if (aConfig.mOnMesh)
{
mServer->OutputFormat("o");
}
if (aConfig.mStable)
{
mServer->OutputFormat("s");
}
if (aConfig.mNdDns)
{
mServer->OutputFormat("n");
}
if (aConfig.mDp)
{
mServer->OutputFormat("D");
}
switch (aConfig.mPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
mServer->OutputFormat(" low");
break;
case OT_ROUTE_PREFERENCE_MED:
mServer->OutputFormat(" med");
break;
case OT_ROUTE_PREFERENCE_HIGH:
mServer->OutputFormat(" high");
break;
}
mServer->OutputFormat("\r\n");
}
otError Interpreter::ProcessPrefixList(void)
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
@@ -2582,62 +2661,20 @@ otError Interpreter::ProcessPrefixList(void)
while (otBorderRouterGetNextOnMeshPrefix(mInstance, &iterator, &config) == OT_ERROR_NONE)
{
mServer->OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(config.mPrefix.mPrefix.mFields.m16[0]),
HostSwap16(config.mPrefix.mPrefix.mFields.m16[1]),
HostSwap16(config.mPrefix.mPrefix.mFields.m16[2]),
HostSwap16(config.mPrefix.mPrefix.mFields.m16[3]), config.mPrefix.mLength);
if (config.mPreferred)
{
mServer->OutputFormat("p");
}
if (config.mSlaac)
{
mServer->OutputFormat("a");
}
if (config.mDhcp)
{
mServer->OutputFormat("d");
}
if (config.mConfigure)
{
mServer->OutputFormat("c");
}
if (config.mDefaultRoute)
{
mServer->OutputFormat("r");
}
if (config.mOnMesh)
{
mServer->OutputFormat("o");
}
if (config.mStable)
{
mServer->OutputFormat("s");
}
switch (config.mPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
mServer->OutputFormat(" low\r\n");
break;
case OT_ROUTE_PREFERENCE_MED:
mServer->OutputFormat(" med\r\n");
break;
case OT_ROUTE_PREFERENCE_HIGH:
mServer->OutputFormat(" high\r\n");
break;
}
OutputPrefix(config);
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (otBackboneRouterGetState(mInstance) == OT_BACKBONE_ROUTER_STATE_DISABLED)
{
SuccessOrExit(otBackboneRouterGetDomainPrefix(mInstance, &config));
mServer->OutputFormat("- ");
OutputPrefix(config);
}
// Else already printed via above while loop.
exit:
#endif
return OT_ERROR_NONE;
}
+1
View File
@@ -318,6 +318,7 @@ private:
otError ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixRemove(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixList(void);
void OutputPrefix(otBorderRouterConfig &aConfig);
#endif
void ProcessPromiscuous(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
+17 -1
View File
@@ -75,9 +75,16 @@ void otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConf
otError otBackboneRouterRegister(otInstance *aInstance)
{
otError error = OT_ERROR_NONE;
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<BackboneRouter::Local>().AddService(true /* Force registration */);
SuccessOrExit(error = instance.Get<BackboneRouter::Local>().AddService(true /* Force registration */));
instance.Get<NetworkData::Notifier>().HandleServerDataUpdated();
exit:
return error;
}
uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance)
@@ -94,4 +101,13 @@ void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitte
return instance.Get<BackboneRouter::Local>().SetRegistrationJitter(aJitter);
}
otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig)
{
Instance &instance = *static_cast<Instance *>(aInstance);
OT_ASSERT(aConfig != NULL);
return instance.Get<BackboneRouter::Local>().GetDomainPrefix(*aConfig);
}
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
+27 -30
View File
@@ -54,52 +54,49 @@ otError otBorderRouterGetNetData(otInstance *aInstance, bool aStable, uint8_t *a
otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig)
{
uint8_t flags = 0;
otError error = OT_ERROR_NONE;
Instance &instance = *static_cast<Instance *>(aInstance);
OT_ASSERT(aConfig != NULL);
// Add Prefix validation check:
// Thread 1.1 Specification 5.13.2 says
// "A valid prefix MUST NOT allow both DHCPv6 and SLAAC for address configuration"
VerifyOrExit(!aConfig->mDhcp || !aConfig->mSlaac, error = OT_ERROR_INVALID_ARGS);
if (aConfig->mPreferred)
error = instance.Get<NetworkData::Local>().AddOnMeshPrefix(*aConfig);
#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)
{
flags |= NetworkData::BorderRouterEntry::kPreferredFlag;
}
// Restore local server data
instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aConfig->mPrefix.mPrefix.mFields.m8,
aConfig->mPrefix.mLength);
if (aConfig->mSlaac)
{
flags |= NetworkData::BorderRouterEntry::kSlaacFlag;
instance.Get<BackboneRouter::Local>().SetDomainPrefix(*aConfig);
}
#endif
if (aConfig->mDhcp)
{
flags |= NetworkData::BorderRouterEntry::kDhcpFlag;
}
if (aConfig->mConfigure)
{
flags |= NetworkData::BorderRouterEntry::kConfigureFlag;
}
if (aConfig->mDefaultRoute)
{
flags |= NetworkData::BorderRouterEntry::kDefaultRouteFlag;
}
if (aConfig->mOnMesh)
{
flags |= NetworkData::BorderRouterEntry::kOnMeshFlag;
}
return instance.Get<NetworkData::Local>().AddOnMeshPrefix(
aConfig->mPrefix.mPrefix.mFields.m8, aConfig->mPrefix.mLength, aConfig->mPreference, flags, aConfig->mStable);
exit:
return error;
}
otError otBorderRouterRemoveOnMeshPrefix(otInstance *aInstance, const otIp6Prefix *aPrefix)
{
otError error = OT_ERROR_NONE;
Instance &instance = *static_cast<Instance *>(aInstance);
OT_ASSERT(aPrefix != NULL);
return instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
error = instance.Get<BackboneRouter::Local>().RemoveDomainPrefix(*aPrefix);
if (error == OT_ERROR_NOT_FOUND)
#endif
{
error = instance.Get<NetworkData::Local>().RemoveOnMeshPrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength);
}
return error;
}
otError otBorderRouterGetNextOnMeshPrefix(otInstance * aInstance,
+115 -13
View File
@@ -57,6 +57,7 @@ Local::Local(Instance &aInstance)
, mRegistrationJitter(Mle::kBackboneRouterRegistrationJitter)
, mIsServiceAdded(false)
{
mDomainPrefixConfig.mPrefix.mLength = 0;
}
void Local::SetEnabled(bool aEnable)
@@ -66,14 +67,18 @@ void Local::SetEnabled(bool aEnable)
if (aEnable)
{
SetState(OT_BACKBONE_ROUTER_STATE_SECONDARY);
AddDomainPrefixToNetworkData();
AddService();
}
else
{
RemoveDomainPrefixFromNetworkData();
RemoveService();
SetState(OT_BACKBONE_ROUTER_STATE_DISABLED);
}
Get<NetworkData::Notifier>().HandleServerDataUpdated();
exit:
return;
}
@@ -82,7 +87,10 @@ void Local::Reset(void)
{
VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED);
RemoveService();
if (RemoveService() == OT_ERROR_NONE)
{
Get<NetworkData::Notifier>().HandleServerDataUpdated();
}
if (mState == OT_BACKBONE_ROUTER_STATE_PRIMARY)
{
@@ -127,12 +135,15 @@ void Local::SetConfig(const BackboneRouterConfig &aConfig)
if (update)
{
IgnoreReturnValue(AddService());
Get<Notifier>().Signal(OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL);
if (AddService() == OT_ERROR_NONE)
{
Get<NetworkData::Notifier>().HandleServerDataUpdated();
}
}
otLogDebgNetData("BBR local: seqno (%d), delay (%ds), timeout (%ds)", mSequenceNumber, mReregistrationDelay,
mMlrTimeout);
LogBackboneRouterService("Set", OT_ERROR_NONE);
}
otError Local::AddService(bool aForce)
@@ -158,29 +169,24 @@ otError Local::AddService(bool aForce)
reinterpret_cast<const uint8_t *>(&serverData), sizeof(serverData)));
mIsServiceAdded = true;
Get<NetworkData::Notifier>().HandleServerDataUpdated();
otLogInfoNetData("BBR Service added: seqno (%d), delay (%ds), timeout (%ds)", mSequenceNumber, mReregistrationDelay,
mMlrTimeout);
exit:
otLogInfoNetData("Add BBR Service: %s", otThreadErrorToString(error));
LogBackboneRouterService("Add", error);
return error;
}
otError Local::RemoveService(void)
{
otError error = OT_ERROR_NONE;
otError error;
uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
SuccessOrExit(error = Get<NetworkData::Local>().RemoveService(NetworkData::ServiceTlv::kThreadEnterpriseNumber,
&serviceData, sizeof(serviceData)));
mIsServiceAdded = false;
Get<NetworkData::Notifier>().HandleServerDataUpdated();
exit:
otLogInfoNetData("Remove BBR Service %s", otThreadErrorToString(error));
LogBackboneRouterService("Remove", error);
return error;
}
@@ -227,7 +233,10 @@ void Local::UpdateBackboneRouterPrimary(Leader::State aState, const BackboneRout
mReregistrationDelay = aConfig.mReregistrationDelay;
mMlrTimeout = aConfig.mMlrTimeout;
Get<Notifier>().Signal(OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL);
AddService(true /* Force registration to refresh and restore Primary state */);
if (AddService(true /* Force registration to refresh and restore Primary state */) == OT_ERROR_NONE)
{
Get<NetworkData::Notifier>().HandleServerDataUpdated();
}
}
else
{
@@ -238,6 +247,99 @@ exit:
return;
}
otError Local::GetDomainPrefix(NetworkData::OnMeshPrefixConfig &aConfig)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mDomainPrefixConfig.mPrefix.mLength > 0, error = OT_ERROR_NOT_FOUND);
aConfig = mDomainPrefixConfig;
exit:
return error;
}
otError Local::RemoveDomainPrefix(const otIp6Prefix &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);
if (IsEnabled())
{
RemoveDomainPrefixFromNetworkData();
}
mDomainPrefixConfig.mPrefix.mLength = 0;
exit:
return error;
}
void Local::SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig)
{
if (IsEnabled())
{
RemoveDomainPrefixFromNetworkData();
}
mDomainPrefixConfig = aConfig;
LogDomainPrefix("Set", OT_ERROR_NONE);
if (IsEnabled())
{
AddDomainPrefixToNetworkData();
}
}
void Local::RemoveDomainPrefixFromNetworkData(void)
{
otError error = OT_ERROR_NOT_FOUND; // only used for logging.
if (mDomainPrefixConfig.mPrefix.mLength > 0)
{
error = Get<NetworkData::Local>().RemoveOnMeshPrefix(mDomainPrefixConfig.mPrefix.mPrefix.mFields.m8,
mDomainPrefixConfig.mPrefix.mLength);
}
LogDomainPrefix("Remove", error);
}
void Local::AddDomainPrefixToNetworkData(void)
{
otError error = OT_ERROR_NOT_FOUND; // only used for logging.
if (mDomainPrefixConfig.mPrefix.mLength > 0)
{
error = Get<NetworkData::Local>().AddOnMeshPrefix(mDomainPrefixConfig);
}
LogDomainPrefix("Add", error);
}
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_NETDATA == 1)
void Local::LogDomainPrefix(const char *aAction, otError aError)
{
otLogInfoNetData("%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));
}
void Local::LogBackboneRouterService(const char *aAction, otError aError)
{
otLogInfoNetData("%s BBR Service: seqno (%d), delay (%ds), timeout (%ds), %s", aAction, mSequenceNumber,
mReregistrationDelay, mMlrTimeout, otThreadErrorToString(aError));
}
#endif
} // namespace BackboneRouter
} // namespace ot
+43
View File
@@ -42,6 +42,7 @@
#include "backbone_router/leader.hpp"
#include "net/netif.hpp"
#include "thread/network_data.hpp"
namespace ot {
@@ -162,9 +163,49 @@ public:
*/
void UpdateBackboneRouterPrimary(Leader::State aState, const BackboneRouterConfig &aConfig);
/**
* This method gets the Domain Prefix configuration.
*
* @param[out] aConfig A reference to the Domain Prefix configuration.
*
* @retval OT_ERROR_NONE Successfully got the Domain Prefix configuration.
* @retval OT_ERROR_NOT_FOUND No Domain Prefix was configured.
*
*/
otError GetDomainPrefix(NetworkData::OnMeshPrefixConfig &aConfig);
/**
* This method removes the local Domain Prefix configuration.
*
* @param[in] aPrefix A reference to the IPv6 Domain Prefix.
*
* @retval OT_ERROR_NONE Successfully removed the Domain Prefix.
* @retval OT_ERROR_INVALID_ARGS @p aPrefix is invalid.
* @retval OT_ERROR_NOT_FOUND No Domain Prefix was configured or @p aPrefix doesn't match.
*
*/
otError RemoveDomainPrefix(const otIp6Prefix &aPrefix);
/**
* This method sets the local Domain Prefix configuration.
*
* @param[in] aConfig A reference to the Domain Prefix configuration.
*
*/
void SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig);
private:
void SetState(BackboneRouterState aState);
otError RemoveService(void);
void AddDomainPrefixToNetworkData(void);
void RemoveDomainPrefixFromNetworkData(void);
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_NETDATA == 1)
void LogBackboneRouterService(const char *aAction, otError aError);
void LogDomainPrefix(const char *aAction, otError aError);
#else
void LogBackboneRouterService(const char *, otError) {}
void LogDomainPrefix(const char *, otError) {}
#endif
BackboneRouterState mState;
uint32_t mMlrTimeout;
@@ -176,6 +217,8 @@ private:
// Used to check whether or not in restore stage after reset or whether to remove
// Backbone Router service for Secondary Backbone Router if it was added by force.
bool mIsServiceAdded;
NetworkData::OnMeshPrefixConfig mDomainPrefixConfig;
};
} // namespace BackboneRouter
+4 -1
View File
@@ -1744,7 +1744,10 @@ void MleRouter::HandleStateUpdateTimer(void)
// If no Backbone Router service after jitter, try to register its own Backbone Router Service.
if (!Get<BackboneRouter::Leader>().HasPrimary())
{
Get<BackboneRouter::Local>().AddService();
if (Get<BackboneRouter::Local>().AddService() == OT_ERROR_NONE)
{
Get<NetworkData::Notifier>().HandleServerDataUpdated();
}
}
}
}
+2
View File
@@ -218,6 +218,8 @@ otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16,
aConfig.mOnMesh = borderRouterEntry->IsOnMesh();
aConfig.mStable = borderRouter->IsStable();
aConfig.mRloc16 = borderRouterEntry->GetRloc();
aConfig.mNdDns = borderRouterEntry->IsNdDns();
aConfig.mDp = borderRouterEntry->IsDp();
iterator.SetEntryIndex(index + 1);
+49 -4
View File
@@ -54,9 +54,54 @@ Local::Local(Instance &aInstance)
}
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
otError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable)
otError Local::AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig)
{
return AddPrefix(aPrefix, aPrefixLength, NetworkDataTlv::kTypeBorderRouter, aPrf, aFlags, aStable);
uint16_t flags = 0;
if (aConfig.mPreferred)
{
flags |= BorderRouterEntry::kPreferredFlag;
}
if (aConfig.mSlaac)
{
flags |= BorderRouterEntry::kSlaacFlag;
}
if (aConfig.mDhcp)
{
flags |= BorderRouterEntry::kDhcpFlag;
}
if (aConfig.mConfigure)
{
flags |= BorderRouterEntry::kConfigureFlag;
}
if (aConfig.mDefaultRoute)
{
flags |= BorderRouterEntry::kDefaultRouteFlag;
}
if (aConfig.mOnMesh)
{
flags |= BorderRouterEntry::kOnMeshFlag;
}
if (aConfig.mNdDns)
{
flags |= BorderRouterEntry::kNdDnsFlag;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (aConfig.mDp)
{
flags |= BorderRouterEntry::kDpFlag;
}
#endif
return AddPrefix(aConfig.mPrefix.mPrefix.mFields.m8, aConfig.mPrefix.mLength, NetworkDataTlv::kTypeBorderRouter,
aConfig.mPreference, flags, aConfig.mStable);
}
otError Local::RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
@@ -78,7 +123,7 @@ otError Local::AddPrefix(const uint8_t * aPrefix,
uint8_t aPrefixLength,
NetworkDataTlv::Type aSubTlvType,
int8_t aPrf,
uint8_t aFlags,
uint16_t aFlags,
bool aStable)
{
otError error = OT_ERROR_NONE;
@@ -86,7 +131,7 @@ otError Local::AddPrefix(const uint8_t * aPrefix,
uint8_t subTlvLength;
PrefixTlv *prefixTlv;
VerifyOrExit(prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aPrefixLength > 0 && prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS);
switch (aPrf)
{
+3 -7
View File
@@ -73,18 +73,14 @@ public:
/**
* This method adds a Border Router 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] aFlags The Border Router Flags value.
* @param[in] aStable The Stable value.
* @param[in] aConfig A reference to the on mesh perfix configuration.
*
* @retval OT_ERROR_NONE Successfully added the Border Router entry.
* @retval OT_ERROR_NO_BUFS Insufficient space to add the Border Router entry.
* @retval OT_ERROR_INVALID_ARGS The prefix is mesh local prefix.
*
*/
otError AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable);
otError AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig);
/**
* This method removes a Border Router entry from the Thread Network Data.
@@ -182,7 +178,7 @@ private:
uint8_t aPrefixLength,
NetworkDataTlv::Type aSubTlvType,
int8_t aPrf,
uint8_t aFlags,
uint16_t aFlags,
bool aStable);
otError RemovePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, NetworkDataTlv::Type aSubTlvType);
void UpdateRloc(PrefixTlv &aPrefix);
+41 -89
View File
@@ -521,14 +521,16 @@ class BorderRouterEntry
public:
enum
{
kPreferenceOffset = 6,
kPreferenceOffset = 14,
kPreferenceMask = 3 << kPreferenceOffset,
kPreferredFlag = 1 << 5,
kSlaacFlag = 1 << 4,
kDhcpFlag = 1 << 3,
kConfigureFlag = 1 << 2,
kDefaultRouteFlag = 1 << 1,
kOnMeshFlag = 1 << 0,
kPreferredFlag = 1 << 13,
kSlaacFlag = 1 << 12,
kDhcpFlag = 1 << 11,
kConfigureFlag = 1 << 10,
kDefaultRouteFlag = 1 << 9,
kOnMeshFlag = 1 << 8,
kNdDnsFlag = 1 << 7,
kDpFlag = 1 << 6,
};
/**
@@ -538,8 +540,7 @@ public:
void Init(void)
{
SetRloc(Mac::kShortAddrInvalid);
mFlags = 0;
mReserved = 0;
mFlags = 0;
}
/**
@@ -558,20 +559,23 @@ public:
void SetRloc(uint16_t aRloc16) { mRloc = HostSwap16(aRloc16); }
/**
* This method returns the Flags byte value.
* This method returns the Flags value.
*
* @returns The Flags byte value.
* @returns The Flags value.
*
*/
uint8_t GetFlags(void) const { return mFlags & ~kPreferenceMask; }
uint16_t GetFlags(void) const { return HostSwap16(mFlags) & ~kPreferenceMask; }
/**
* This method sets the Flags byte value.
* This method sets the Flags value.
*
* @param[in] aFlags The Flags byte value.
* @param[in] aFlags The Flags value.
*
*/
void SetFlags(uint8_t aFlags) { mFlags = (mFlags & kPreferenceMask) | (aFlags & ~kPreferenceMask); }
void SetFlags(uint16_t aFlags)
{
mFlags = HostSwap16((HostSwap16(mFlags) & kPreferenceMask) | (aFlags & ~kPreferenceMask));
}
/**
* This method returns the Preference value.
@@ -579,7 +583,10 @@ public:
* @returns the Preference value.
*
*/
int8_t GetPreference(void) const { return static_cast<int8_t>(mFlags) >> kPreferenceOffset; }
int8_t GetPreference(void) const
{
return static_cast<int8_t>(static_cast<int16_t>(HostSwap16(mFlags)) >> kPreferenceOffset);
}
/**
* This method sets the Preference value.
@@ -589,7 +596,7 @@ public:
*/
void SetPreference(int8_t aPrf)
{
mFlags = (mFlags & ~kPreferenceMask) | ((static_cast<uint8_t>(aPrf) << kPreferenceOffset) & kPreferenceMask);
mFlags = HostSwap16(GetFlags() | ((static_cast<uint16_t>(aPrf) << kPreferenceOffset) & kPreferenceMask));
}
/**
@@ -599,19 +606,7 @@ public:
* @retval FALSE If the Preferred flag is not set.
*
*/
bool IsPreferred(void) const { return (mFlags & kPreferredFlag) != 0; }
/**
* This method clears the Preferred flag.
*
*/
void ClearPreferred(void) { mFlags &= ~kPreferredFlag; }
/**
* This method sets the Preferred flag.
*
*/
void SetPreferred(void) { mFlags |= kPreferredFlag; }
bool IsPreferred(void) const { return (HostSwap16(mFlags) & kPreferredFlag) != 0; }
/**
* This method indicates whether or not the SLAAC flag is set.
@@ -620,19 +615,7 @@ public:
* @retval FALSE If the SLAAC flag is not set.
*
*/
bool IsSlaac(void) const { return (mFlags & kSlaacFlag) != 0; }
/**
* This method clears the SLAAC flag.
*
*/
void ClearSlaac(void) { mFlags &= ~kSlaacFlag; }
/**
* This method sets the SLAAC flag.
*
*/
void SetSlaac(void) { mFlags |= kSlaacFlag; }
bool IsSlaac(void) const { return (HostSwap16(mFlags) & kSlaacFlag) != 0; }
/**
* This method indicates whether or not the DHCP flag is set.
@@ -641,19 +624,7 @@ public:
* @retval FALSE If the DHCP flag is not set.
*
*/
bool IsDhcp(void) const { return (mFlags & kDhcpFlag) != 0; }
/**
* This method clears the DHCP flag.
*
*/
void ClearDhcp(void) { mFlags &= ~kDhcpFlag; }
/**
* This method sets the DHCP flag.
*
*/
void SetDhcp(void) { mFlags |= kDhcpFlag; }
bool IsDhcp(void) const { return (HostSwap16(mFlags) & kDhcpFlag) != 0; }
/**
* This method indicates whether or not the Configure flag is set.
@@ -662,19 +633,7 @@ public:
* @retval FALSE If the Configure flag is not set.
*
*/
bool IsConfigure(void) const { return (mFlags & kConfigureFlag) != 0; }
/**
* This method clears the Configure flag.
*
*/
void ClearConfigure(void) { mFlags &= ~kConfigureFlag; }
/**
* This method sets the Configure flag.
*
*/
void SetConfigure(void) { mFlags |= kConfigureFlag; }
bool IsConfigure(void) const { return (HostSwap16(mFlags) & kConfigureFlag) != 0; }
/**
* This method indicates whether or not the Default Route flag is set.
@@ -683,19 +642,7 @@ public:
* @retval FALSE If the Default Route flag is not set.
*
*/
bool IsDefaultRoute(void) const { return (mFlags & kDefaultRouteFlag) != 0; }
/**
* This method clears the Default Route flag.
*
*/
void ClearDefaultRoute(void) { mFlags &= ~kDefaultRouteFlag; }
/**
* This method sets the Default Route flag.
*
*/
void SetDefaultRoute(void) { mFlags |= kDefaultRouteFlag; }
bool IsDefaultRoute(void) const { return (HostSwap16(mFlags) & kDefaultRouteFlag) != 0; }
/**
* This method indicates whether or not the On-Mesh flag is set.
@@ -704,19 +651,25 @@ public:
* @retval FALSE If the On-Mesh flag is not set.
*
*/
bool IsOnMesh(void) const { return (mFlags & kOnMeshFlag) != 0; }
bool IsOnMesh(void) const { return (HostSwap16(mFlags) & kOnMeshFlag) != 0; }
/**
* This method clears the On-Mesh flag.
* This method indicates whether or not the Nd-Dns flag is set.
*
* @retval TRUE If the Nd-Dns flag is set.
* @retval FALSE If the Nd-Dns flag is not set.
*
*/
void ClearOnMesh(void) { mFlags &= ~kOnMeshFlag; }
bool IsNdDns(void) const { return (HostSwap16(mFlags) & kNdDnsFlag) != 0; }
/**
* This method sets the On-Mesh flag.
* This method indicates whether or not the Domain Prefix flag is set.
*
* @retval TRUE If the Domain Prefix flag is set.
* @retval FALSE If the Domain Prefix flag is not set.
*
*/
void SetOnMesh(void) { mFlags |= kOnMeshFlag; }
bool IsDp(void) const { return (HostSwap16(mFlags) & kDpFlag) != 0; }
/**
* This method returns a pointer to the next BorderRouterEntry
@@ -736,8 +689,7 @@ public:
private:
uint16_t mRloc;
uint8_t mFlags;
uint8_t mReserved;
uint16_t mFlags;
} OT_TOOL_PACKED_END;
/**
+2
View File
@@ -56,6 +56,8 @@ REALM_LOCAL_ALL_ROUTERS_ADDRESS = 'ff03::2'
LINK_LOCAL_ALL_NODES_ADDRESS = 'ff02::1'
LINK_LOCAL_ALL_ROUTERS_ADDRESS = 'ff02::2'
DOMAIN_PREFIX = 'fd00:7d03:7d03:7d03::/64'
DEFAULT_MASTER_KEY = bytearray([
0x00,
0x11,
+9
View File
@@ -509,6 +509,15 @@ class Node:
self.send_command(cmd)
self._expect('Done')
def set_domain_prefix(self, prefix):
flags = 'prosD'
self.add_prefix(prefix, flags)
self.register_netdata()
def remove_domain_prefix(self, prefix):
self.remove_prefix(prefix)
self.register_netdata()
def set_link_quality(self, addr, lqi):
cmd = 'macfilter rss add-lqi %s %s' % (addr, lqi)
self.send_command(cmd)
@@ -30,6 +30,7 @@
import unittest
import thread_cert
import config
LEADER_1_1 = 1
BBR_1 = 2
@@ -90,10 +91,12 @@ class TestBackboneRouterService(thread_cert.TestCase):
WAIT_TIME = WAIT_ATTACH
self.simulator.go(WAIT_TIME)
self.assertEqual(self.nodes[LEADER_1_1].get_state(), 'leader')
self.simulator.set_lowpan_context(1, config.DOMAIN_PREFIX)
# 1) First Backbone Router would become the Primary.
self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
self.nodes[BBR_1].set_backbone_router(seqno=1)
self.nodes[BBR_1].start()
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
@@ -111,6 +114,7 @@ class TestBackboneRouterService(thread_cert.TestCase):
self.nodes[BBR_1].reset()
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
self.nodes[BBR_1].enable_backbone_router()
self.nodes[BBR_1].start()
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
@@ -135,6 +139,7 @@ class TestBackboneRouterService(thread_cert.TestCase):
ROUTER_SELECTION_JITTER)
self.nodes[BBR_1].set_bbr_registration_jitter(
BBR_REGISTRATION_JITTER)
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
self.nodes[BBR_1].enable_backbone_router()
self.nodes[BBR_1].start()
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
@@ -157,6 +162,7 @@ class TestBackboneRouterService(thread_cert.TestCase):
# by default.
self.nodes[BBR_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
self.nodes[BBR_2].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
self.nodes[BBR_2].set_domain_prefix(config.DOMAIN_PREFIX)
self.nodes[BBR_2].start()
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
self.simulator.go(WAIT_TIME)
@@ -168,12 +174,16 @@ class TestBackboneRouterService(thread_cert.TestCase):
# Enable Backbone function, it will stay at Secondary state as
# there is Primary Backbone Router already.
# Here removes the Domain Prefix before enabling backbone function
# intentionally to avoid SRV_DATA.ntf due to prefix inconsistency.
self.nodes[BBR_2].remove_domain_prefix(config.DOMAIN_PREFIX)
self.nodes[BBR_2].enable_backbone_router()
self.nodes[BBR_2].set_backbone_router(seqno=255)
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
self.simulator.go(WAIT_TIME)
self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
'Secondary')
# Check no SRV_DATA.ntf.
messages = self.simulator.get_messages_sent_by(BBR_2)
msg = messages.next_coap_message('0.02', '/a/sd', False)
@@ -219,6 +229,7 @@ class TestBackboneRouterService(thread_cert.TestCase):
# Verify that BBR_2 stays at Secondary.
self.nodes[BBR_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
self.nodes[BBR_2].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
self.nodes[BBR_2].enable_backbone_router()
self.nodes[BBR_2].interface_up()
self.nodes[BBR_2].thread_start()