From 31ebf2d08106e65e9805c187e37657fe053fbe67 Mon Sep 17 00:00:00 2001 From: kurogeek Date: Thu, 8 Oct 2026 08:13:23 +0000 Subject: [PATCH] machines/stellio: deprecate withdrawn DHCPv6-PD prefixes (interim copy of cnx-network fa11327) After the reboot vlan-lan got its /64 at boot, but IPv6 still failed for clients: the first PPPoE session lands on another AIS BNG, is torn down minutes later, and the reconnect brings a different /64 (07:53 2405:9800:b911:91e3 -> 07:57 b910:1f5d). networkd announces the new prefix at once but never deprecates the old one (systemd#29651), so clients keep it preferred for up to 30 minutes and source selection sends every connection from a dead address. router-radv-deprecate.service watches vlan-* for networkd removing a dynamic address and sends RAs with that /64 at preferred lifetime 0 via a short-lived radvd (SIGKILLed: no shutdown RA). Identical script to the upstream commit; drop once the cnx-network input is bumped past it. Verified on stellio: the stale prefix flipped to deprecated on the client at the first RA and pings resumed; a synthetic dynamic address removed from vlan-lan produced the same RA end to end. --- machines/stellio/configuration.nix | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/machines/stellio/configuration.nix b/machines/stellio/configuration.nix index bc25f2a9..6793a738 100644 --- a/machines/stellio/configuration.nix +++ b/machines/stellio/configuration.nix @@ -108,6 +108,65 @@ systemd.network.networks."40-vlan-lan".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x0"; systemd.network.networks."40-vlan-mgmt".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x1"; + # Interim copy of cnx-network-clan fa11327 (router/ipv6: deprecate + # withdrawn DHCPv6-PD prefixes); drop when the input is bumped past it. + # networkd never deprecates a prefix it stops announcing (systemd#29651): + # on every reboot the first PPPoE session lands on another AIS BNG, is + # torn down minutes later, and the reconnect brings a different /64. + # networkd announces the new prefix at once but clients keep the old + # one preferred for the rest of its 1800 s lifetime, so RFC 6724 source + # selection picks the dead prefix and every v6 connection fails for up + # to 30 minutes (2026-10-08 07:57). Watch vlan-* for networkd removing a + # dynamic (PD) address and send a few RAs with that /64 at preferred + # lifetime 0; radvd is only the packet generator, killed hard after ~7 s + # so it sends no shutdown RA (router lifetime 0) and does not keep + # deprecating a prefix the ISP re-delegates on reconnect. + systemd.services.router-radv-deprecate = { + description = "Deprecate withdrawn DHCPv6-PD prefixes on the VLANs"; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-networkd.service" ]; + path = [ + pkgs.iproute2 + pkgs.ipcalc + pkgs.radvd + ]; + serviceConfig = { + Restart = "always"; + RestartSec = 2; + RuntimeDirectory = "router-radv-deprecate"; + }; + script = '' + conf=$RUNTIME_DIRECTORY/radvd.conf + pid=$RUNTIME_DIRECTORY/radvd.pid + # "Deleted 4: vlan-lan inet6 2001:db8::1/64 scope global dynamic mngtmpaddr \ valid_lft ..." + ip -o -6 monitor address | while read -r event _ dev _ addr _ scope rest; do + [[ $event == Deleted && $dev == vlan-* && $scope == global && $rest == *dynamic* ]] || continue + prefix="$(ipcalc --no-decorate -n "$addr")/''${addr##*/}" + echo "$dev: deprecating withdrawn prefix $prefix" + cat > "$conf" </dev/null || true + wait $! || true + done + ''; + }; + systemd.services.heartbeat-push = { description = "Heartbeat push to uptime monitor"; serviceConfig = {