From 54a80516d2617375bd26c9debeb946510e54c0b3 Mon Sep 17 00:00:00 2001 From: Tim Spriggs <1257463-imoverclocked@users.noreply.gitlab.freedesktop.org> Date: Tue, 5 May 2026 23:15:00 -0700 Subject: [PATCH] core: dhcp6: support PD and LL route Fixes Issue 1948: IPv6 link with RA and PD should be healthy Use-case: Some ISPs provide IPv6 via Prefix Delegation (PD) only. The default route is link-local and the prefix can be used via an "ipv6.method: shared" interface. This patch considers PD as a valid address for dhcp6 lease/link purposes. --- NEWS | 3 +++ src/core/dhcp/nm-dhcp-systemd.c | 45 +++++++++++++++++---------------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index 214b65a91f..6ceb5d8397 100644 --- a/NEWS +++ b/NEWS @@ -64,6 +64,9 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! * Allow configuring all bond options in nmtui by introducing a "other options" field, which covers options not already covered by a dedicated input field. +* IPv6 interfaces that receive PD via DHCPv6 are considered healthy without a + non-temporary address. The delegated prefix can be used via an interface + configured with "ipv6.method: shared" ============================================= NetworkManager-1.56 diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index b570f7e507..d9367b7d7c 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -92,6 +92,7 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro const char *s; nm_auto_free_gstring GString *str = NULL; int num, i; + gboolean has_any_addresses = FALSE; nm_assert(lease); @@ -107,8 +108,29 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro NM_DHCP_OPTION_DHCP6_NM_IAID, nm_dhcp_iaid_to_hexstr(config->v6.iaid, iaid_buf)); + { + struct in6_addr prefix; + uint8_t prefix_len; + + nm_gstring_prepare(&str); + sd_dhcp6_lease_pd_iterator_reset(lease); + while (!sd_dhcp6_lease_get_pd_prefix(lease, &prefix, &prefix_len)) { + nm_gstring_add_space_delimiter(str); + nm_inet6_ntop(&prefix, addr_str); + g_string_append_printf(str, "%s/%u", addr_str, prefix_len); + sd_dhcp6_lease_pd_iterator_next(lease); + } + if (str->len > 0) { + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_IA_PD, + str->str); + has_any_addresses = TRUE; + } + } + if (!config->v6.info_only) { - gboolean has_any_addresses = FALSE; uint64_t lft_pref; uint64_t lft_valid; @@ -166,27 +188,6 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro str->str); } - { - struct in6_addr prefix; - uint8_t prefix_len; - - nm_gstring_prepare(&str); - sd_dhcp6_lease_pd_iterator_reset(lease); - while (!sd_dhcp6_lease_get_pd_prefix(lease, &prefix, &prefix_len)) { - nm_gstring_add_space_delimiter(str); - nm_inet6_ntop(&prefix, addr_str); - g_string_append_printf(str, "%s/%u", addr_str, prefix_len); - sd_dhcp6_lease_pd_iterator_next(lease); - } - if (str->len > 0) { - nm_dhcp_option_add_option(options, - TRUE, - AF_INET6, - NM_DHCP_OPTION_DHCP6_IA_PD, - str->str); - } - } - num = sd_dhcp6_lease_get_domains(lease, &domains); if (num > 0) { nm_gstring_prepare(&str);