busybox: Parse multiple IPv6 addresses in dhcp6 This patches the udhcpc6 application to add environment variables for each of the IA_ADDR blocks in the DHCP adverisement instead of just the first one. It keeps the same variable for the 0th address to retain backwards compatability. You can expect the mapping IA_ADDR[0] -> $ipv6_0 IA_ADDR[1] -> $ipv6_1 ... IA_ADDR[n] -> $ipv6_n Tested: Verified working with multi-IP DHCP by manually triggering udhcp6 with environment info printed during an installation job. Fusion-Link: fusion2 N/A Google-Bug-Id: 428779896 Change-Id: If4f3a5584eecf8b5f822a92144a01e4996963452 Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/recipes-core/busybox/busybox/0001-d6_dhcpc-Parse-multiple-IA_ADDR-options-into-env.patch b/recipes-core/busybox/busybox/0001-d6_dhcpc-Parse-multiple-IA_ADDR-options-into-env.patch new file mode 100644 index 0000000..19661e7 --- /dev/null +++ b/recipes-core/busybox/busybox/0001-d6_dhcpc-Parse-multiple-IA_ADDR-options-into-env.patch
@@ -0,0 +1,62 @@ +From ed8f79fcc6324fbfc41a60b4be32650546818782 Mon Sep 17 00:00:00 2001 +From: "William A. Kennington III" <wak@google.com> +Date: Mon, 8 Sep 2025 12:09:27 -0700 +Subject: [PATCH] d6_dhcpc: Parse multiple IA_ADDR options into env + +We have multiple IPv6 address passed via DHCP and need to parse out all +the IA_ADDR options so the system can assign all addresses, not just the +first one. + +Upstream-Status: Pending +Justification: Fairly easy to maintain downstream as the concept is +clear. Need to figure out if we can upstream it or something similar. +Signed-off-by: William A. Kennington III <wak@google.com> +--- + networking/udhcp/d6_common.h | 1 + + networking/udhcp/d6_dhcpc.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h +index 3cbfbb89e..b5e514bf4 100644 +--- a/networking/udhcp/d6_common.h ++++ b/networking/udhcp/d6_common.h +@@ -156,6 +156,7 @@ struct client6_data_t { + struct d6_option *ia_pd; + char **env_ptr; + unsigned env_idx; ++ unsigned num_ip_opts; + /* link-local IPv6 address */ + struct in6_addr ll_ip6; + } FIX_ALIASING; +diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c +index 19c961d5c..eb3e5bc7f 100644 +--- a/networking/udhcp/d6_dhcpc.c ++++ b/networking/udhcp/d6_dhcpc.c +@@ -310,11 +310,15 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end) + break; + + sprint_nip6(ipv6str, option + 4); ++ *new_env() = xasprintf("ipv6_%u=%s", client6_data.num_ip_opts, ipv6str); + *new_env() = xasprintf("ipv6=%s", ipv6str); + + move_from_unaligned32(v32, option + 4 + 16 + 4); + v32 = ntohl(v32); ++ *new_env() = xasprintf("lease_%u=%u", client6_data.num_ip_opts, (unsigned)v32); + *new_env() = xasprintf("lease=%u", (unsigned)v32); ++ ++ client6_data.num_ip_opts++; + break; + + //case D6_OPT_ORO: +@@ -451,6 +455,8 @@ static char **fill_envp(const uint8_t *option, const uint8_t *option_end) + + *new_env() = xasprintf("interface=%s", client_data.interface); + ++ client6_data.num_ip_opts = 0; ++ + if (option) + option_to_env(option, option_end); + +-- +2.51.0.384.g4c02a37b29-goog +
diff --git a/recipes-core/busybox/busybox_%.bbappend b/recipes-core/busybox/busybox_%.bbappend index f3b65e6..d38e313 100644 --- a/recipes-core/busybox/busybox_%.bbappend +++ b/recipes-core/busybox/busybox_%.bbappend
@@ -2,4 +2,5 @@ SRC_URI:append:gbmc = " \ file://0001-Work-around-broken-dhcp6-server-on-fqdn-option.patch \ file://0001-udhcpc6-return-error-in-interface-read-failure-in-dh.patch \ + file://0001-d6_dhcpc-Parse-multiple-IA_ADDR-options-into-env.patch \ "