From 7f3457859eafaf2ed1dec3f80d557c9922bad64b Mon Sep 17 00:00:00 2001 From: kurogeek Date: Thu, 8 Oct 2026 08:36:59 +0000 Subject: [PATCH] machines/stellio: stop deprecating a PD prefix the ISP re-delegates (sync with cnx-network 45643d6) The ISP modem restart at 08:19 re-delegated the same /64 five seconds after the PPPoE drop. networkd re-announced it at once, but the fixed 7 s radvd run kept sending preferred-lifetime-0 RAs for it, so clients sat on a deprecated prefix until networkd's next periodic RA and IPv6 stayed broken for minutes. Send one RA per radvd start, up to three 3 s apart, and skip each one if the /64 is already back on the interface. Verified on stellio with the rendered script: a prefix gone for good -> three RAs; the PD address removed and re-added 4 s later -> two RAs, then "is back, leaving it announced", client preferred again and pinging over v6. --- machines/stellio/configuration.nix | 40 ++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/machines/stellio/configuration.nix b/machines/stellio/configuration.nix index 6793a738..ad6866a0 100644 --- a/machines/stellio/configuration.nix +++ b/machines/stellio/configuration.nix @@ -108,7 +108,7 @@ 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 + # Interim copy of cnx-network-clan 45643d6 (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 @@ -117,10 +117,12 @@ # 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. + # dynamic (PD) address and send up to three RAs with that /64 at + # preferred lifetime 0, one short-lived radvd per RA (SIGKILLed: no + # shutdown RA with router lifetime 0), stopping as soon as the prefix is + # back on the interface -- a plain flap re-delegates the same /64 within + # seconds and a deprecating RA sent after networkd re-announced it would + # leave clients deprecated until the next periodic RA (08:19 today). systemd.services.router-radv-deprecate = { description = "Deprecate withdrawn DHCPv6-PD prefixes on the VLANs"; wantedBy = [ "multi-user.target" ]; @@ -138,11 +140,18 @@ script = '' conf=$RUNTIME_DIRECTORY/radvd.conf pid=$RUNTIME_DIRECTORY/radvd.pid + + # /64s of the global addresses currently on an interface. + prefixes_on() { + ip -o -6 addr show dev "$1" scope global | while read -r _ _ _ a _; do + echo "$(ipcalc --no-decorate -n "$a")/''${a##*/}" + done + } + # "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 + for _ in 1 2 3; do + if prefixes_on "$dev" | grep -qxF "$prefix"; then + echo "$dev: $prefix is back, leaving it announced" + break + fi + echo "$dev: deprecating withdrawn prefix $prefix" + rm -f "$pid" + # radvd sends its first RA on start; the next would follow 3-4 s later. + radvd -C "$conf" -p "$pid" -n -m stderr & + sleep 1 + kill -KILL $! 2>/dev/null || true + wait $! || true + sleep 2 + done done ''; };