]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-relay: reimplement DHCP relay agent and drop legacy DHCP relay mode from...
authorDaan De Meyer <daan@amutable.com>
Thu, 21 May 2026 14:23:44 +0000 (16:23 +0200)
committerGitHub <noreply@github.com>
Thu, 21 May 2026 14:23:44 +0000 (16:23 +0200)
1  2 
src/libsystemd/sd-common/sd-forward.h
src/network/networkd-address.c
src/network/networkd-link.c
src/network/networkd-link.h
src/systemd/meson.build
test/test-network/systemd-networkd-tests.py

Simple merge
index 3880eab47fe9aff78ee00b828a7081e04fc0ab0e,9737ae02881da51633a1b64a34db2b5f8a0b8981..11337126e58915f6c962aff5c3daa8aa87acd006
@@@ -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) {
Simple merge
Simple merge
Simple merge