[dhcp6] obsolete DHCPv6 Server Unicast Option per RFC 9915 (#13146)

This commit updates the DHCPv6 Prefix Delegation (PD) client to
comply with RFC 9915, which obsoletes the Server Unicast option
(Option 12) and the UseMulticast status code.

Changes:
- Removed `mServerAddress` and `ProcessServerUnicastOption()` from
  `Dhcp6PdClient`.
- Modified `Dhcp6PdClient::SendMessage` to always transmit via
  multicast to `ff02::1:2`.
- Removed `UseMulticast` status code handling in `HandleReply()`.
- Added `otMessageFree` weak stub in simulation platform's
  `infra_if.c` to resolve linking errors on simulation radio-only
  targets when DHCPv6 PD client is enabled.
- Updated `test_dhcp6_pd_client.cpp` to expect multicast and
  removed the obsolete UseMulticast test case.
This commit is contained in:
Jonathan Hui
2026-05-27 10:31:00 -07:00
committed by GitHub
parent 494a4868a3
commit dcbd870245
5 changed files with 75 additions and 333 deletions
+12 -70
View File
@@ -51,7 +51,6 @@ Dhcp6PdClient::Dhcp6PdClient(Instance &aInstance)
, mMaxSolicitTimeout(kMaxSolicitTimeout)
, mTimer(aInstance)
{
mServerAddress.Clear();
}
void Dhcp6PdClient::Start(void)
@@ -268,18 +267,9 @@ void Dhcp6PdClient::SendMessage(void)
SuccessOrExit(AppendIaPdOption(*message));
LogInfo("Sending %s %s%s", MsgTypeToString(msgType),
mServerAddress.IsUnspecified() ? "(multicast)" : "(unicast) to:",
mServerAddress.IsUnspecified() ? "" : mServerAddress.ToString().AsCString());
LogInfo("Sending %s (multicast)", MsgTypeToString(msgType));
if (!mServerAddress.IsUnspecified())
{
dstAddr = mServerAddress;
}
else
{
GetAllRelayAgentsAndServersMulticastAddress(dstAddr);
}
GetAllRelayAgentsAndServersMulticastAddress(dstAddr);
Get<InfraIf>().SendDhcp6(*message.Release(), dstAddr);
@@ -535,7 +525,7 @@ void Dhcp6PdClient::HandleAdvertise(const Message &aMessage)
mPdPrefix = *favoredPdPrefix;
SaveServerDuidAndAddress(aMessage);
SaveServerDuid(aMessage);
if (!mRetxTracker.IsFirstAttempt() || (preference == 255))
{
@@ -562,20 +552,6 @@ void Dhcp6PdClient::HandleReply(const Message &aMessage)
ExitNow();
}
if (status == StatusCodeOption::kUseMulticast)
{
// Per RFC 8514 Section 18.2.10, if the client receives a Reply
// message with a status code of UseMulticast, the client
// records the receipt of the message and sends subsequent
// messages to the server using multicast. The client re-sends the
// original message using multicast.
VerifyOrExit(!mServerAddress.IsUnspecified());
mServerAddress.Clear();
SendMessage();
ExitNow();
}
if (mState == kStateReleasing)
{
// Per RFC 8415 Section 18.2.10.2: When the client receives a
@@ -599,7 +575,7 @@ void Dhcp6PdClient::HandleReply(const Message &aMessage)
ExitNow();
}
SaveServerDuidAndAddress(aMessage);
SaveServerDuid(aMessage);
CommitPdPrefix(*favoredPdPrefix);
ExitNow();
@@ -613,7 +589,7 @@ void Dhcp6PdClient::HandleReply(const Message &aMessage)
if (matchedPdPrefix != nullptr)
{
SaveServerDuidAndAddress(aMessage);
SaveServerDuid(aMessage);
CommitPdPrefix(*matchedPdPrefix);
if (mPdPrefix.mPreferredLifetime >= kMinPreferredLifetime)
@@ -631,7 +607,7 @@ void Dhcp6PdClient::HandleReply(const Message &aMessage)
if (favoredPdPrefix != nullptr)
{
SaveServerDuidAndAddress(aMessage);
SaveServerDuid(aMessage);
CommitPdPrefix(*favoredPdPrefix);
ExitNow();
}
@@ -685,32 +661,20 @@ Dhcp6PdClient::PdPrefix *Dhcp6PdClient::SelectFavoredPrefix(PdPrefixArray &aPdPr
return favoredPdPrefix;
}
void Dhcp6PdClient::SaveServerDuidAndAddress(const Message &aMessage)
void Dhcp6PdClient::SaveServerDuid(const Message &aMessage)
{
// Reads the server DUID and Server Unicast option from the given
// message and saves them. The message is assumed to have already
// been validated to contain a Server ID option.
// Reads the server DUID from the given message and saves it.
// The message is assumed to have already been validated to contain
// a Server ID option.
OffsetRange serverDuidOffsetRange;
Ip6::Address serverAddress;
OffsetRange serverDuidOffsetRange;
SuccessOrAssert(ServerIdOption::ReadDuid(aMessage, serverDuidOffsetRange));
mServerDuid.SetLength(static_cast<uint8_t>(serverDuidOffsetRange.GetLength()));
aMessage.ReadBytes(serverDuidOffsetRange, mServerDuid.GetArrayBuffer());
ProcessServerUnicastOption(aMessage, serverAddress);
if (!serverAddress.IsUnspecified())
{
mServerAddress = serverAddress;
}
}
void Dhcp6PdClient::ClearServerDuid(void)
{
mServerDuid.Clear();
mServerAddress.Clear();
}
void Dhcp6PdClient::ClearServerDuid(void) { mServerDuid.Clear(); }
void Dhcp6PdClient::ClearPdPrefix(void)
{
@@ -970,28 +934,6 @@ exit:
return shouldSkip;
}
void Dhcp6PdClient::ProcessServerUnicastOption(const Message &aMessage, Ip6::Address &aServerAddress) const
{
// Searches the message for a `ServerUnicastOption`. If found, the
// server address is retrieved from it. Otherwise, `aServerAddress`
// is set to `::` (unspecified address).
OffsetRange offsetRange;
ServerUnicastOption serverUnicastOption;
aServerAddress.Clear();
SuccessOrExit(Option::FindOption(aMessage, Option::kServerUnicast, offsetRange));
SuccessOrExit(aMessage.Read(offsetRange, serverUnicastOption));
aServerAddress = serverUnicastOption.GetServerAddress();
LogInfo("Processed Sever Unicast Option, serverAddr:%s", aServerAddress.ToString().AsCString());
exit:
return;
}
void Dhcp6PdClient::ProcessPreferenceOption(const Message &aMessage, uint8_t &aPreference) const
{
// Searches for `PreferenceOption` in the message. If it is not
+8 -10
View File
@@ -246,9 +246,8 @@ private:
PdPrefixArray &aPdPrefixes,
Dhcp6::StatusCodeOption::Status &aStatus) const;
bool ShouldSkipPrefixOption(const Dhcp6::IaPrefixOption &aPrefixOption) const;
void ProcessServerUnicastOption(const Message &aMessage, Ip6::Address &aServerAddress) const;
void ProcessPreferenceOption(const Message &aMessage, uint8_t &aPreference) const;
void SaveServerDuidAndAddress(const Message &aMessage);
void SaveServerDuid(const Message &aMessage);
void ClearServerDuid(void);
void ClearPdPrefix(void);
void CommitPdPrefix(const PdPrefix &aPdPrefix);
@@ -259,14 +258,13 @@ private:
using DelayTimer = TimerMilliIn<Dhcp6PdClient, &Dhcp6PdClient::HandleTimer>;
State mState;
bool mPdPrefixCommited;
RetxTracker mRetxTracker;
uint32_t mMaxSolicitTimeout;
PdPrefix mPdPrefix;
ServerDuid mServerDuid;
Ip6::Address mServerAddress;
DelayTimer mTimer;
State mState;
bool mPdPrefixCommited;
RetxTracker mRetxTracker;
uint32_t mMaxSolicitTimeout;
PdPrefix mPdPrefix;
ServerDuid mServerDuid;
DelayTimer mTimer;
};
} // namespace BorderRouter
-31
View File
@@ -161,7 +161,6 @@ public:
kElapsedTime = 8, ///< Elapsed Time Option.
kRelayMessage = 9, ///< Relay Message Option.
kAuthentication = 11, ///< Authentication Option.
kServerUnicast = 12, ///< Server Unicast Option.
kStatusCode = 13, ///< Status Code Option.
kRapidCommit = 14, ///< Rapid Commit Option.
kUserClass = 15, ///< User Class Option.
@@ -1019,36 +1018,6 @@ private:
// Can be followed by sub-options.
} OT_TOOL_PACKED_END;
/**
* Represents a Server Unicast Option.
*/
OT_TOOL_PACKED_BEGIN
class ServerUnicastOption : public Option
{
public:
/**
* Initializes the DHCPv6 Option.
*/
void Init(void) { SetCode(kServerUnicast), SetLength(sizeof(*this) - sizeof(Option)); }
/**
* Returns the server IPv6 address.
*
* @returns the server IPv6 address.
*/
const Ip6::Address &GetServerAddress(void) const { return mServerAddress; }
/**
* Sets the server IPv6 address.
*
* @param[in] aServerAddress The server IPv6 address.
*/
void SetServerAddress(const Ip6::Address &aServerAddress) { mServerAddress = aServerAddress; }
private:
Ip6::Address mServerAddress;
} OT_TOOL_PACKED_END;
/**
* Represents an SOL_MAX_RT Option (Max Solicit timeout value).
*/