[dhcp6] clean up Prefix Agent state management in DHCPv6 server (#3646)

* introduce a new class for managing Prefix Agent state
* combine prefix and ALOC into the same class
This commit is contained in:
Jonathan Hui
2019-03-07 09:12:20 -08:00
committed by GitHub
parent 62971bfe93
commit 0938be7f84
2 changed files with 149 additions and 165 deletions
+45 -129
View File
@@ -53,40 +53,31 @@ namespace Dhcp6 {
Dhcp6Server::Dhcp6Server(Instance &aInstance)
: InstanceLocator(aInstance)
, mSocket(GetNetif().GetIp6().GetUdp())
, mPrefixAgentsCount(0)
, mPrefixAgentsMask(0)
{
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
memset(&(mPrefixAgents[i]), 0, sizeof(PrefixAgent));
memset(&mAgentsAloc[i], 0, sizeof(mAgentsAloc[i]));
}
mPrefixAgentsCount = 0;
mPrefixAgentsMask = 0;
memset(mPrefixAgents, 0, sizeof(mPrefixAgents));
}
otError Dhcp6Server::UpdateService(void)
{
ThreadNetif & netif = GetNetif();
otError error = OT_ERROR_NONE;
bool found;
uint8_t i;
uint16_t rloc16 = netif.GetMle().GetRloc16();
Ip6::Address * address = NULL;
otError error = OT_ERROR_NONE;
ThreadNetif & netif = GetNetif();
uint16_t rloc16 = netif.GetMle().GetRloc16();
otNetworkDataIterator iterator;
otBorderRouterConfig config;
Lowpan::Context lowpanContext;
// remove dhcp agent aloc and prefix delegation
for (i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
for (int i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
found = false;
bool found = false;
if (!mAgentsAloc[i].mValid)
if (!mPrefixAgents[i].IsValid())
{
continue;
}
address = &(mAgentsAloc[i].GetAddress());
iterator = OT_NETWORK_DATA_ITERATOR_INIT;
while (netif.GetNetworkDataLeader().GetNextOnMeshPrefix(&iterator, rloc16, &config) == OT_ERROR_NONE)
@@ -96,10 +87,9 @@ otError Dhcp6Server::UpdateService(void)
continue;
}
netif.GetNetworkDataLeader().GetContext(*static_cast<const Ip6::Address *>(&(config.mPrefix.mPrefix)),
lowpanContext);
error = netif.GetNetworkDataLeader().GetContext(mPrefixAgents[i].GetPrefix(), lowpanContext);
if (address->mFields.m8[15] == lowpanContext.mContextId)
if ((error == OT_ERROR_NONE) && (mPrefixAgents[i].GetContextId() == lowpanContext.mContextId))
{
// still in network data
found = true;
@@ -109,10 +99,8 @@ otError Dhcp6Server::UpdateService(void)
if (!found)
{
netif.GetNetworkDataLeader().GetContext(address->mFields.m8[15], lowpanContext);
netif.RemoveUnicastAddress(mAgentsAloc[i]);
mAgentsAloc[i].mValid = false;
RemovePrefixAgent(lowpanContext.mPrefix);
mPrefixAgents[i].Clear();
mPrefixAgentsCount--;
}
}
@@ -121,57 +109,17 @@ otError Dhcp6Server::UpdateService(void)
while (netif.GetNetworkDataLeader().GetNextOnMeshPrefix(&iterator, rloc16, &config) == OT_ERROR_NONE)
{
found = false;
if (!config.mDhcp)
{
continue;
}
netif.GetNetworkDataLeader().GetContext(*static_cast<const Ip6::Address *>(&config.mPrefix.mPrefix),
lowpanContext);
error = netif.GetNetworkDataLeader().GetContext(static_cast<const Ip6::Address &>(config.mPrefix.mPrefix),
lowpanContext);
for (i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
if (error == OT_ERROR_NONE)
{
address = &(mAgentsAloc[i].GetAddress());
if ((mAgentsAloc[i].mValid) && (address->mFields.m8[15] == lowpanContext.mContextId))
{
found = true;
break;
}
}
// already added
if (found)
{
continue;
}
for (i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
if (!mAgentsAloc[i].mValid)
{
address = &(mAgentsAloc[i].GetAddress());
memcpy(address, netif.GetMle().GetMeshLocalPrefix().m8, sizeof(otMeshLocalPrefix));
address->mFields.m16[4] = HostSwap16(0x0000);
address->mFields.m16[5] = HostSwap16(0x00ff);
address->mFields.m16[6] = HostSwap16(0xfe00);
address->mFields.m8[14] = Ip6::Address::kAloc16Mask;
address->mFields.m8[15] = lowpanContext.mContextId;
mAgentsAloc[i].mPrefixLength = 64;
mAgentsAloc[i].mPreferred = true;
mAgentsAloc[i].mValid = true;
netif.AddUnicastAddress(mAgentsAloc[i]);
AddPrefixAgent(config.mPrefix);
break;
}
}
// if no available Dhcp Agent Aloc resources
if (i == OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES)
{
ExitNow(error = OT_ERROR_NO_BUFS);
AddPrefixAgent(config.mPrefix, lowpanContext);
}
}
@@ -184,7 +132,6 @@ otError Dhcp6Server::UpdateService(void)
Stop();
}
exit:
return error;
}
@@ -202,48 +149,29 @@ void Dhcp6Server::Stop(void)
mSocket.Close();
}
otError Dhcp6Server::AddPrefixAgent(otIp6Prefix &aIp6Prefix)
otError Dhcp6Server::AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext)
{
otError error = OT_ERROR_NO_BUFS;
otError error = OT_ERROR_NONE;
PrefixAgent *newEntry = NULL;
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
for (int i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
if (mPrefixAgents[i].GetPrefix()->mLength != 0)
if (!mPrefixAgents[i].IsValid())
{
continue;
newEntry = &mPrefixAgents[i];
}
else if (mPrefixAgents[i].IsPrefixMatch(aIp6Prefix))
{
// already added
ExitNow();
}
mPrefixAgents[i].SetPrefix(aIp6Prefix);
mPrefixAgentsCount++;
ExitNow(error = OT_ERROR_NONE);
}
exit:
return error;
}
VerifyOrExit(newEntry != NULL, error = OT_ERROR_NO_BUFS);
otError Dhcp6Server::RemovePrefixAgent(const uint8_t *aIp6Address)
{
otError error = OT_ERROR_NOT_FOUND;
otIp6Prefix *prefix = NULL;
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
prefix = mPrefixAgents[i].GetPrefix();
if (prefix->mLength == 0)
{
continue;
}
if (otIp6PrefixMatch(&(prefix->mPrefix), reinterpret_cast<const otIp6Address *>(aIp6Address)) >=
prefix->mLength)
{
memset(&(mPrefixAgents[i]), 0, sizeof(PrefixAgent));
mPrefixAgentsCount--;
ExitNow(error = OT_ERROR_NONE);
}
}
newEntry->Set(aIp6Prefix, GetNetif().GetMle().GetMeshLocalPrefix(), aContext.mContextId);
GetNetif().AddUnicastAddress(newEntry->GetAloc());
mPrefixAgentsCount++;
exit:
return error;
@@ -381,9 +309,8 @@ exit:
otError Dhcp6Server::ProcessIaAddress(Message &aMessage, uint16_t aOffset)
{
otError error = OT_ERROR_NONE;
otIp6Prefix *prefix = NULL;
IaAddress option;
otError error = OT_ERROR_NONE;
IaAddress option;
VerifyOrExit(((aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option)) &&
option.GetLength() == (sizeof(option) - sizeof(Dhcp6Option))),
@@ -392,14 +319,7 @@ otError Dhcp6Server::ProcessIaAddress(Message &aMessage, uint16_t aOffset)
// mask matching prefix
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
prefix = mPrefixAgents[i].GetPrefix();
if (prefix->mLength == 0)
{
continue;
}
if (otIp6PrefixMatch(&option.GetAddress(), &prefix->mPrefix) >= prefix->mLength)
if (mPrefixAgents[i].IsValid() && mPrefixAgents[i].IsPrefixMatch(option.GetAddress()))
{
mPrefixAgentsMask |= (1 << i);
break;
@@ -514,33 +434,28 @@ otError Dhcp6Server::AppendStatusCode(Message &aMessage, Status aStatus)
otError Dhcp6Server::AppendIaAddress(Message &aMessage, ClientIdentifier &aClient)
{
otError error = OT_ERROR_NONE;
otIp6Prefix *prefix = NULL;
otError error = OT_ERROR_NONE;
// if specified, only apply specified prefixes
if (mPrefixAgentsMask)
{
// if specified, only apply specified prefixes
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
if (mPrefixAgentsMask & (1 << i))
{
prefix = mPrefixAgents[i].GetPrefix();
SuccessOrExit(error = AddIaAddress(aMessage, *prefix, aClient));
SuccessOrExit(error = AddIaAddress(aMessage, mPrefixAgents[i].GetPrefix(), aClient));
}
}
}
else // if not specified, apply all configured prefixes
else
{
// if not specified, apply all configured prefixes
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
{
prefix = mPrefixAgents[i].GetPrefix();
if (prefix->mLength == 0)
if (mPrefixAgents[i].IsValid())
{
continue;
SuccessOrExit(error = AddIaAddress(aMessage, mPrefixAgents[i].GetPrefix(), aClient));
}
SuccessOrExit(error = AddIaAddress(aMessage, *prefix, aClient));
}
}
@@ -548,17 +463,18 @@ exit:
return error;
}
otError Dhcp6Server::AddIaAddress(Message &aMessage, otIp6Prefix &aIp6Prefix, ClientIdentifier &aClient)
otError Dhcp6Server::AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClient)
{
otError error = OT_ERROR_NONE;
IaAddress option;
option.Init();
memcpy(option.GetAddress().mFields.m8, &aIp6Prefix.mPrefix, 8);
memcpy(option.GetAddress().mFields.m8, &aPrefix, OT_IP6_PREFIX_SIZE);
option.GetAddress().SetIid(*reinterpret_cast<Mac::ExtAddress *>(aClient.GetDuidLinkLayerAddress()));
option.SetPreferredLifetime(OT_DHCP6_DEFAULT_PREFERRED_LIFETIME);
option.SetValidLifetime(OT_DHCP6_DEFAULT_VALID_LIFETIME);
SuccessOrExit(error = aMessage.Append(&option, sizeof(option)));
exit:
return error;
}
+104 -36
View File
@@ -66,35 +66,6 @@ namespace Dhcp6 {
#define OT_DHCP6_DEFAULT_PREFERRED_LIFETIME 0xffffffffU
#define OT_DHCP6_DEFAULT_VALID_LIFETIME 0xffffffffU
/**
* This class implements prefix agent.
*
*/
OT_TOOL_PACKED_BEGIN
class PrefixAgent
{
public:
/**
* This method returns the reference to the IPv6 prefix.
*
* @returns A reference to the IPv6 prefix.
*
*/
otIp6Prefix *GetPrefix(void) { return &mIp6Prefix; }
/**
* This method sets the IPv6 prefix.
*
* @param[in] aIp6Prefix The reference to the IPv6 prefix to set.
*
*/
void SetPrefix(otIp6Prefix &aIp6Prefix) { memcpy(&mIp6Prefix, &aIp6Prefix, sizeof(otIp6Prefix)); }
private:
otIp6Prefix mIp6Prefix; ///< prefix
} OT_TOOL_PACKED_END;
class Dhcp6Server : public InstanceLocator
{
public:
@@ -113,11 +84,109 @@ public:
otError UpdateService();
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) &&
(otIp6PrefixMatch(&mPrefix.mPrefix, &aPrefix.mPrefix) >= mPrefix.mLength);
}
/**
* This method indicates whether or not @p aAddress has a matching prefix.
*
* @param[in] aAddress The IPv6 address to compare.
*
* @retval TRUE if the address has a matching prefix.
* @retval FALSE if the address does not have a matching prefix.
*
*/
bool IsPrefixMatch(const otIp6Address &aAddress) const
{
return (otIp6PrefixMatch(&mPrefix.mPrefix, &aAddress) >= mPrefix.mLength);
}
/**
* This method indicates whether or not this entry is valid.
*
* @retval TRUE if this entry is valid.
* @retval FALSE if this entry is not valid.
*
*/
bool IsValid(void) const { return mAloc.mValid; }
/**
* This method sets the entry to invalid.
*
*/
void Clear(void) { mAloc.mValid = false; }
/**
* This method returns the 6LoWPAN context ID.
*
* @returns The 6LoWPAN context ID.
*
*/
uint8_t GetContextId(void) const { return mAloc.mAddress.mFields.m8[15]; }
/**
* This method returns the ALOC.
*
* @returns the ALOC.
*
*/
Ip6::NetifUnicastAddress &GetAloc(void) { return mAloc; }
/**
* This method returns the IPv6 prefix.
*
* @returns The IPv6 prefix.
*
*/
const Ip6::Address &GetPrefix(void) const { return static_cast<const Ip6::Address &>(mPrefix.mPrefix); }
/**
* This method sets the ALOC.
*
* @param[in] aPrefix The IPv6 prefix.
* @param[in] aMeshLocalPrefix The Mesh Local Prefix.
* @param[in] aContextId The 6LoWPAN Context ID.
*
*/
void Set(const otIp6Prefix &aPrefix, const otMeshLocalPrefix &aMeshLocalPrefix, uint8_t aContextId)
{
mPrefix = aPrefix;
memcpy(&mAloc.mAddress, &aMeshLocalPrefix, OT_IP6_PREFIX_SIZE);
mAloc.mAddress.mFields.m16[4] = HostSwap16(0x0000);
mAloc.mAddress.mFields.m16[5] = HostSwap16(0x00ff);
mAloc.mAddress.mFields.m16[6] = HostSwap16(0xfe00);
mAloc.mAddress.mFields.m8[14] = Ip6::Address::kAloc16Mask;
mAloc.mAddress.mFields.m8[15] = aContextId;
mAloc.mPrefixLength = 64;
mAloc.mPreferred = true;
mAloc.mValid = true;
}
private:
Ip6::NetifUnicastAddress mAloc;
otIp6Prefix mPrefix;
};
void Start(void);
void Stop(void);
otError AddPrefixAgent(otIp6Prefix &aIp6Prefix);
otError RemovePrefixAgent(const uint8_t *aIp6Address);
otError AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext);
otError AppendHeader(Message &aMessage, uint8_t *aTransactionId);
otError AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClient);
@@ -128,7 +197,7 @@ private:
otError AppendRapidCommit(Message &aMessage);
otError AppendVendorSpecificInformation(Message &aMessage);
otError AddIaAddress(Message &aMessage, otIp6Prefix &aIp6Prefix, ClientIdentifier &aClient);
otError AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClient);
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
@@ -145,10 +214,9 @@ private:
Ip6::UdpSocket mSocket;
Ip6::NetifUnicastAddress mAgentsAloc[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES];
PrefixAgent mPrefixAgents[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES];
uint8_t mPrefixAgentsMask;
uint8_t mPrefixAgentsCount;
PrefixAgent mPrefixAgents[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES];
uint8_t mPrefixAgentsCount;
uint8_t mPrefixAgentsMask;
};
} // namespace Dhcp6