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.
This commit is contained in:
1 parent
31ebf2d081
commit
7f3457859e
1 file changed
+25
-7
@@ -108,7 +108,7 @@
|
|||||||
systemd.network.networks."40-vlan-lan".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x0";
|
systemd.network.networks."40-vlan-lan".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x0";
|
||||||
systemd.network.networks."40-vlan-mgmt".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x1";
|
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.
|
# withdrawn DHCPv6-PD prefixes); drop when the input is bumped past it.
|
||||||
# networkd never deprecates a prefix it stops announcing (systemd#29651):
|
# networkd never deprecates a prefix it stops announcing (systemd#29651):
|
||||||
# on every reboot the first PPPoE session lands on another AIS BNG, is
|
# 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
|
# 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
|
# 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
|
# 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
|
# dynamic (PD) address and send up to three RAs with that /64 at
|
||||||
# lifetime 0; radvd is only the packet generator, killed hard after ~7 s
|
# preferred lifetime 0, one short-lived radvd per RA (SIGKILLed: no
|
||||||
# so it sends no shutdown RA (router lifetime 0) and does not keep
|
# shutdown RA with router lifetime 0), stopping as soon as the prefix is
|
||||||
# deprecating a prefix the ISP re-delegates on reconnect.
|
# 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 = {
|
systemd.services.router-radv-deprecate = {
|
||||||
description = "Deprecate withdrawn DHCPv6-PD prefixes on the VLANs";
|
description = "Deprecate withdrawn DHCPv6-PD prefixes on the VLANs";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
@@ -138,11 +140,18 @@
|
|||||||
script = ''
|
script = ''
|
||||||
conf=$RUNTIME_DIRECTORY/radvd.conf
|
conf=$RUNTIME_DIRECTORY/radvd.conf
|
||||||
pid=$RUNTIME_DIRECTORY/radvd.pid
|
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 ..."
|
# "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
|
ip -o -6 monitor address | while read -r event _ dev _ addr _ scope rest; do
|
||||||
[[ $event == Deleted && $dev == vlan-* && $scope == global && $rest == *dynamic* ]] || continue
|
[[ $event == Deleted && $dev == vlan-* && $scope == global && $rest == *dynamic* ]] || continue
|
||||||
prefix="$(ipcalc --no-decorate -n "$addr")/''${addr##*/}"
|
prefix="$(ipcalc --no-decorate -n "$addr")/''${addr##*/}"
|
||||||
echo "$dev: deprecating withdrawn prefix $prefix"
|
|
||||||
cat > "$conf" <<EOF
|
cat > "$conf" <<EOF
|
||||||
interface $dev {
|
interface $dev {
|
||||||
AdvSendAdvert on;
|
AdvSendAdvert on;
|
||||||
@@ -158,11 +167,20 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
EOF
|
EOF
|
||||||
|
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"
|
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 &
|
radvd -C "$conf" -p "$pid" -n -m stderr &
|
||||||
sleep 7
|
sleep 1
|
||||||
kill -KILL $! 2>/dev/null || true
|
kill -KILL $! 2>/dev/null || true
|
||||||
wait $! || true
|
wait $! || true
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user