From: Paul Donald Date: Thu, 18 Dec 2025 14:10:24 +0000 (+0100) Subject: dhcpv6: use stable IAID for IA_NA X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=9a4d6fe802d21e4fc1b84f7d55b5c3c23e71d6ba;p=project%2Fodhcp6c.git dhcpv6: use stable IAID for IA_NA 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 --- 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);