From ac9d0ce62e1e97eb35d037c4d6a447e300603f06 Mon Sep 17 00:00:00 2001 From: khromenokroman Date: Wed, 21 Oct 2026 22:11:37 +0200 Subject: [PATCH] network: request DHCPv6 information again on "networkctl renew" When the DHCPv6 client runs in the information request mode, the client is stopped after a reply is received. Hence, previously "networkctl renew" tried to restart the client. That did nothing when the client was started by RA, and otherwise the new request was refused until the information refresh time passed. Let's request the information again in that case. As the hostname is not sent in the information request mode, a hostname change does not trigger a new Information-Request message. --- NEWS | 4 +++- man/networkctl.xml | 3 ++- src/network/networkd-dhcp6.c | 20 +++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 533dc9487e9..46860068363 100644 --- a/NEWS +++ b/NEWS @@ -121,7 +121,9 @@ CHANGES WITH 263 in spe: may be used to disable this. * "networkctl renew" now renews the DHCPv6 lease too, not only the - DHCPv4 lease. + DHCPv4 lease. When the DHCPv6 client runs in the information + request mode, the information, e.g. DNS servers, is requested + again. Changes in systemd-sysupdate: diff --git a/man/networkctl.xml b/man/networkctl.xml index bfe275749cd..49df27a35e5 100644 --- a/man/networkctl.xml +++ b/man/networkctl.xml @@ -496,7 +496,8 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR) DEVICE… Renew dynamic configurations e.g. addresses received from DHCPv4 and DHCPv6 - servers. Takes interface name or index number. + servers. When the DHCPv6 client runs in the information request mode, the information, e.g. DNS + servers, is requested again. Takes interface name or index number. diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index bc71fe8b300..00f43845933 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -838,7 +838,7 @@ static bool dhcp6_hostname_is_from_lease(Link *link) { } int dhcp6_update_hostname(Link *link) { - int r; + int inf_req, r; assert(link); @@ -856,6 +856,13 @@ int dhcp6_update_hostname(Link *link) { if (r < 0) return r; + /* No hostname is sent in the information request mode. */ + r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req); + if (r < 0) + return r; + if (inf_req) + return 0; + /* If the hostname was set from the current lease, the server already knows it. The new hostname * will be sent on the next renewal. */ if (dhcp6_hostname_is_from_lease(link)) @@ -879,6 +886,8 @@ int dhcp6_update_hostname(Link *link) { } int dhcp6_renew(Link *link) { + int r; + assert(link); assert(link->manager); @@ -891,13 +900,18 @@ int dhcp6_renew(Link *link) { IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 0; + /* This renews the acquired lease, or in the information request mode, requests the information + * again. This does nothing if no reply is received yet. */ + r = sd_dhcp6_client_send_renew(link->dhcp6_client); + if (r < 0) + return r; + /* The client may have been stopped, e.g. on failure. Let's restart it in that case. This does * nothing when the client is started by RA, as the client will be started on the next RA. */ if (!sd_dhcp6_client_is_running(link->dhcp6_client)) return dhcp6_start(link); - /* This does nothing if no lease is acquired yet. */ - return sd_dhcp6_client_send_renew(link->dhcp6_client); + return 0; } static int dhcp6_process_request(Request *req, Link *link, void *userdata) {