[dhcp6] implement DHCPv6 Prefix Delegation (PD) client (#11584)

This commit introduces the `Dhcp6PdClient` class, which implements
DHCPv6 Prefix Delegation (PD) client functionality. It integrates
with `BorderRouter::RoutingManager` and its `PdPrefixManager`
sub-component. The CMake `OT_BORDER_ROUTING_DHCP6_PD_CLIENT` mapped
to `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE` config
enables this feature.

Previously, the platform layer was expected to implement client
functionality, acquiring and providing the delegated prefix(es) to
the OT stack using `otPlatBorderRouter*` callbacks. This approach
continues to be supported. The `Dhcp6PdClient` feature adds native
support for this functionality in the OpenThread core.

The `Dhcp6PdClient` implementation follows RFC 8415, focusing on
prefix delegation and all required behaviors. The client follows the
standard four-message Solicit/Advertise/Request/Reply exchange to
obtain a delegated prefix, followed by a two-message Renew/Reply or
Rebind/Reply exchange to extend the lifetime of the delegated prefix.
When the prefix is no longer needed, a two-message Release/Reply
exchange ends its lease. The current client implementation does not
support the optional "Reconfigure Accept" mechanism.

A set of `otPlatInfraIfDhcp6PdClient*` platform APIs are also
introduced for use by the `Dhcp6PdClient`. These APIs are used to
enable or disable listening for DHCPv6 messages and to handle sending
and receiving them on the standard client and server UDP ports
(546 and 547), effectively acting as a UDP socket.

This commit also includes a comprehensive unit test covering various
aspects of `Dhcp6PdClient`, including common behaviors and many
specific edge cases.
This commit is contained in:
Abtin Keshavarzian
2025-06-20 19:35:44 -07:00
committed by GitHub
parent faadc5baed
commit f90d50b220
24 changed files with 5030 additions and 50 deletions
+26 -1
View File
@@ -479,6 +479,7 @@ OT_TOOL_WEAK otLinkMetrics otPlatRadioGetEnhAckProbingMetrics(otInstance *, cons
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
OT_TOOL_WEAK bool otPlatInfraIfHasAddress(uint32_t, const otIp6Address *) { return false; }
OT_TOOL_WEAK otError otPlatInfraIfSendIcmp6Nd(uint32_t, const otIp6Address *, const uint8_t *, uint16_t)
@@ -487,7 +488,31 @@ OT_TOOL_WEAK otError otPlatInfraIfSendIcmp6Nd(uint32_t, const otIp6Address *, co
}
OT_TOOL_WEAK otError otPlatInfraIfDiscoverNat64Prefix(uint32_t) { return OT_ERROR_FAILED; }
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE
OT_TOOL_WEAK void otPlatInfraIfDhcp6PdClientSetListeningEnabled(otInstance *aInstance,
bool aEnable,
uint32_t aInfraIfIndex)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aEnable);
OT_UNUSED_VARIABLE(aInfraIfIndex);
}
OT_TOOL_WEAK void otPlatInfraIfDhcp6PdClientSend(otInstance *aInstance,
otMessage *aMessage,
otIp6Address *aDestAddress,
uint32_t aInfraIfIndex)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aDestAddress);
OT_UNUSED_VARIABLE(aInfraIfIndex);
otMessageFree(aMessage);
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE