From: Daan De Meyer Date: Thu, 21 May 2026 14:23:44 +0000 (+0200) Subject: sd-dhcp-relay: reimplement DHCP relay agent and drop legacy DHCP relay mode from... X-Git-Tag: v261-rc1~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e64337ee10e1c31b619ef64ae663afb1bb1e8a70;p=thirdparty%2Fsystemd.git sd-dhcp-relay: reimplement DHCP relay agent and drop legacy DHCP relay mode from sd-dhcp-server (#42130) --- e64337ee10e1c31b619ef64ae663afb1bb1e8a70 diff --cc src/network/networkd-address.c index 3880eab47fe,9737ae02881..11337126e58 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@@ -886,45 -890,15 +890,47 @@@ static int address_drop(Address *in, bo address_del_netlabel(address); - /* FIXME: if the IPv6LL address is dropped, stop DHCPv6, NDISC, RADV. */ if (address->family == AF_INET6 && - in6_addr_equal(&address->in_addr.in6, &link->ipv6ll_address)) + in6_addr_equal(&address->in_addr.in6, &link->ipv6ll_address)) { link->ipv6ll_address = (const struct in6_addr) {}; + Address *a; + bool has_replacement; + + /* If another ready IPv6LL address exists on this link, use it instead. */ + SET_FOREACH(a, link->addresses) { + if (a == address) + continue; + if (a->family != AF_INET6) + continue; + if (!in6_addr_is_link_local(&a->in_addr.in6)) + continue; + if (!address_is_ready(a)) + continue; + link->ipv6ll_address = a->in_addr.in6; + break; + } + + has_replacement = in6_addr_is_set(&link->ipv6ll_address); + + /* Stop engines bound to the dropped IPv6LL source address. Do not return early on error. + * address_detach() and link_update_operstate() must run to keep link state consistent. */ + r = link_ipv6ll_lost(link, &address->in_addr.in6, has_replacement); + if (r < 0) + log_link_warning_errno(link, r, "Failed to stop IPv6 services after IPv6LL loss, ignoring: %m"); + + /* If another IPv6LL address is available, restart engines with it. */ + if (has_replacement) { + r = link_ipv6ll_gained(link); + if (r < 0) + log_link_warning_errno(link, r, "Failed to restart IPv6 services with alternate IPv6LL address, ignoring: %m"); + } + } + ipv4acd_detach(link, address); + (void) link_dhcp_relay_address_dropped(link, address); + address_detach(address); if (!removed_by_us) {