[PATCH v2] dhcpv6: support rapid commit dhcp6 option

Yuxiao Zhang <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
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;
+				}
+				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

-- 
2.55.0.860.g4b6b3295ed-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.