mirror of
https://github.com/espressif/openthread.git
synced 2026-08-16 15:47:46 +00:00
[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:
+45
-129
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user