diff --git a/package/odhcp6c/0002-dhcpv6-use-stable-IAID-for-IA_NA.patch b/package/odhcp6c/0002-dhcpv6-use-stable-IAID-for-IA_NA.patch new file mode 100644 index 0000000000..fc70205ccc --- /dev/null +++ b/package/odhcp6c/0002-dhcpv6-use-stable-IAID-for-IA_NA.patch @@ -0,0 +1,95 @@ +From 9a4d6fe802d21e4fc1b84f7d55b5c3c23e71d6ba Mon Sep 17 00:00:00 2001 +From: Paul Donald +Date: Thu, 18 Dec 2025 15:10:24 +0100 +Subject: [PATCH] dhcpv6: use stable IAID for IA_NA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://www.rfc-editor.org/rfc/rfc8415.html#section-12 + + ........ The IAID is chosen by the client. For any given use of an + IA by the client, the IAID for that IA MUST be consistent across + restarts of the DHCP client. The client may maintain consistency by + either storing the IAID in non-volatile storage or using an algorithm + that will consistently produce the same IAID as long as the + configuration of the client has not changed. + +Signed-off-by: Paul Donald +Link: https://github.com/openwrt/odhcp6c/pull/140 +Signed-off-by: Álvaro Fernández Rojas + +Upstream: https://github.com/openwrt/odhcp6c/commit/9a4d6fe802d21e4fc1b84f7d55b5c3c23e71d6ba + +Signed-off-by: Bernd Kuhls +--- + src/dhcpv6.c | 15 +++++++++++++-- + src/odhcp6c.h | 1 + + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/src/dhcpv6.c b/src/dhcpv6.c +index d8bb8be..97860b1 100644 +--- a/src/dhcpv6.c ++++ b/src/dhcpv6.c +@@ -262,6 +262,9 @@ static struct dhcpv6_stats dhcpv6_stats = {0}; + // config + static struct config_dhcp* config_dhcp = NULL; + ++// store unique ifname hash to use as IA->IAID ++static uint32_t ifname_hash_iaid = 0; ++ + static uint32_t ntohl_unaligned(const uint8_t *data) + { + uint32_t buf; +@@ -542,6 +545,12 @@ void dhcpv6_reset_stats(void) + memset(&dhcpv6_stats, 0, sizeof(dhcpv6_stats)); + } + ++uint32_t hash_ifname(const char *s) { ++ uint32_t h = 0; ++ while (*s) h = h * 31 + *s++; ++ return h; ++} ++ + int init_dhcpv6(const char *ifname) + { + config_dhcp = config_dhcp_get(); +@@ -566,6 +575,8 @@ int init_dhcpv6(const char *ifname) + if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) + goto failure; + ++ ifname_hash_iaid = hash_ifname(ifname); ++ + ifindex = ifr.ifr_ifindex; + + // Set the socket to non-blocking mode +@@ -838,7 +849,7 @@ static void dhcpv6_send(enum dhcpv6_msg req_msg_type, uint8_t trid[3], uint32_t + struct dhcpv6_ia_hdr hdr_ia_na = { + .type = htons(DHCPV6_OPT_IA_NA), + .len = htons(sizeof(hdr_ia_na) - DHCPV6_OPT_HDR_SIZE), +- .iaid = htonl(ifindex), ++ .iaid = htonl(ifname_hash_iaid), + .t1 = 0, + .t2 = 0, + }; +@@ -1392,7 +1403,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _o_unused const int rc, + continue; + + // Test ID +- if (ia_hdr->iaid != htonl(ifindex) && otype == DHCPV6_OPT_IA_NA) ++ if (ia_hdr->iaid != htonl(ifname_hash_iaid) && otype == DHCPV6_OPT_IA_NA) + continue; + + uint16_t code = DHCPV6_Success; +diff --git a/src/odhcp6c.h b/src/odhcp6c.h +index aa73bbc..c57f885 100644 +--- a/src/odhcp6c.h ++++ b/src/odhcp6c.h +@@ -540,6 +540,7 @@ struct odhcp6c_opt { + const char *str; + }; + ++uint32_t hash_ifname(const char *s); + int init_dhcpv6(const char *ifname); + int dhcpv6_get_ia_mode(void); + int dhcpv6_promote_server_cand(void);