Hi Yuxiao,
On 25/08/2026 19:53, Yuxiao Zhang wrote:
> Support rapid commit option code 14 which bypass the advertise and
> request state. The option is enabled by DHCP6_RAPID_COMMIT.
>
> Signed-off-by: Yuxiao Zhang <[email protected]>
> ---
>
> Changes in v2:
> - Reject rapid commit option if option_len != 0
> - Drop redundant NULL check on dhcp6_hdr
>
> cmd/Kconfig | 8 ++++++++
> net/dhcpv6.c | 43 ++++++++++++++++++++++++++++++++++++-------
> net/dhcpv6.h | 2 ++
> 3 files changed, 46 insertions(+), 7 deletions(-)
>
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index ff90a87024c..b3cf3a6d8b6 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -1996,6 +1996,14 @@ config DHCP6_ENTERPRISE_ID
> int "Enterprise ID to send in DHCPv6 Vendor Class Option"
> default 0
>
> +config DHCP6_RAPID_COMMIT
> + bool "Request Rapid Commit (2-message exchange) from DHCPv6 server"
> + default n
> + help
> + Request the Rapid Commit option (option 14) in DHCPv6 Solicit
> + messages to enable a 2-message exchange (Solicit-Reply) rather
> + than the default 4-message exchange.
> +
> endif
>
> config BOOTP_MAY_FAIL
> diff --git a/net/dhcpv6.c b/net/dhcpv6.c
> index 640f089a2e1..5ed8449edb5 100644
> --- a/net/dhcpv6.c
> +++ b/net/dhcpv6.c
> @@ -115,6 +115,9 @@ static int dhcp6_add_option(int option_id, uchar *pkt)
>
> opt_len = sizeof(struct dhcp6_option_ia_na);
> break;
> + case DHCP6_OPTION_RAPID_COMMIT:
> + opt_len = 0;
> + break;
> case DHCP6_OPTION_ORO:
> oro_opt = (struct dhcp6_option_oro *)dhcp_option_start;
> oro_opt->req_option_code[num_oro++] =
> htons(DHCP6_OPTION_OPT_BOOTFILE_URL);
> @@ -194,6 +197,8 @@ static void dhcp6_send_solicit_packet(void)
> pkt += dhcp6_add_option(DHCP6_OPTION_ELAPSED_TIME, pkt);
> pkt += dhcp6_add_option(DHCP6_OPTION_IA_NA, pkt);
> pkt += dhcp6_add_option(DHCP6_OPTION_ORO, pkt);
> + if (IS_ENABLED(CONFIG_DHCP6_RAPID_COMMIT))
> + pkt += dhcp6_add_option(DHCP6_OPTION_RAPID_COMMIT, pkt);
> if (CONFIG_DHCP_PXE_CLIENTARCH != 0xFF)
> pkt += dhcp6_add_option(DHCP6_OPTION_CLIENT_ARCH_TYPE, pkt);
> pkt += dhcp6_add_option(DHCP6_OPTION_VENDOR_CLASS, pkt);
> @@ -448,6 +453,16 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned
> int len)
> }
> sm_params.rx_status.preference = *option_ptr;
> break;
> + case DHCP6_OPTION_RAPID_COMMIT:
> + if (option_len != 0) {
> + debug("Invalid rapid commit option length\n");
> + break;
> + }
> + if (IS_ENABLED(CONFIG_DHCP6_RAPID_COMMIT)) {
> + debug("DHCP6_OPTION_RAPID_COMMIT FOUND\n");
> + sm_params.rx_status.rapid_commit_found = true;
> + }
> + break;
> default:
> debug("Unknown Option ID: %d, skipping parsing\n",
> ntohs(option_hdr->option_id));
> @@ -618,14 +633,28 @@ static void dhcp6_state_machine(bool timeout, uchar
> *rx_pkt, unsigned int len)
> break;
> case DHCP6_SOLICIT:
> if (!timeout) {
> - /* check the rx packet and determine if we can
> transition to next
> - * state.
> - */
> - if (dhcp6_check_advertise_packet(rx_pkt, len))
> - return;
> + struct dhcp6_hdr *dhcp6_hdr = (struct dhcp6_hdr
> *)rx_pkt;
> +
> + if (IS_ENABLED(CONFIG_DHCP6_RAPID_COMMIT) &&
> + dhcp6_hdr->msg_type == DHCP6_MSG_REPLY) {
> + if (dhcp6_check_reply_packet(rx_pkt, len))
> + return;
> + if (!sm_params.rx_status.rapid_commit_found) {
> + debug("[DHCPv6] REPLY received without
> Rapid Commit option, ignoring\n");
> + return;
> + }
dhcp6_check_reply_packet() calls dhcp6_parse_options(), which has side
effects such as updating the bootfile information. I think the Rapid Commit
check
needs to happen before applying the other reply options.
> + debug("REPLY (Rapid Commit) good, transition to
> DONE\n");
> + sm_params.next_state = DHCP6_DONE;
> + } else {
> + /* check the rx packet and determine if we can
> transition to next
> + * state.
> + */
> + if (dhcp6_check_advertise_packet(rx_pkt, len))
> + return;
>
> - debug("ADVERTISE good, transition to REQUEST\n");
> - sm_params.next_state = DHCP6_REQUEST;
> + debug("ADVERTISE good, transition to
> REQUEST\n");
> + sm_params.next_state = DHCP6_REQUEST;
> + }
> } else if (sm_params.retry_cnt == 1) {
> /* If a server UID was received in the first SOLICIT
> period
> * transition to REQUEST
> diff --git a/net/dhcpv6.h b/net/dhcpv6.h
> index d41a3c30615..49f20390730 100644
> --- a/net/dhcpv6.h
> +++ b/net/dhcpv6.h
> @@ -24,6 +24,7 @@
> #define DHCP6_OPTION_PREFERENCE 7
> #define DHCP6_OPTION_ELAPSED_TIME 8
> #define DHCP6_OPTION_STATUS_CODE 13
> +#define DHCP6_OPTION_RAPID_COMMIT 14
> #define DHCP6_OPTION_OPT_BOOTFILE_URL 59
> #define DHCP6_OPTION_OPT_BOOTFILE_PARAM 60
> #define DHCP6_OPTION_SOL_MAX_RT 82
> @@ -152,6 +153,7 @@ struct dhcp6_rx_pkt_status {
> enum dhcp6_status ia_status_code;
> enum dhcp6_status status_code;
> u8 preference;
> + bool rapid_commit_found;
> };
>
> /**
> ---
> base-commit: 527115ef6783cec49e5610c523c124b399011361
> branch: main
>
Thanks,
--
Jerome