46 lines
1.8 KiB
Plaintext
46 lines
1.8 KiB
Plaintext
|
|
#!/bin/sh
|
||
|
|
# Revoke the PPPoE dial lease. Runs every 5s. Only ever takes the WAN AWAY.
|
||
|
|
#
|
||
|
|
# vrrp-wan-reconcile is the single writer and runs every 30s; this is the
|
||
|
|
# watcher, and it exists because `may-dial` must be a LEASE, not a flag.
|
||
|
|
# ConditionPathExists is evaluated at START only -- it can prevent a dial, it can
|
||
|
|
# never revoke one. So if the reconciler stops running (timer masked, box wedged,
|
||
|
|
# someone stops it during maintenance) and the box is then demoted, nothing would
|
||
|
|
# ever hang up: it would keep the one ISP session while the new master tries to
|
||
|
|
# take it.
|
||
|
|
#
|
||
|
|
# Two conditions revoke, both biased the safe way:
|
||
|
|
# - this box does not hold the management VIP
|
||
|
|
# - the lease has not been renewed within LEASE_TTL (the reconciler is dead)
|
||
|
|
#
|
||
|
|
# Deliberately tiny: no config mode, no flock, no commit. It cannot wedge the
|
||
|
|
# router's configuration system, which is what earns it a 5s timer. Running at
|
||
|
|
# 5s rather than the reconciler's 30s is also what shrinks the double-dial
|
||
|
|
# window on a demotion from up to 30s down to about 5.
|
||
|
|
|
||
|
|
CONF=/config/vrrp-wan.conf
|
||
|
|
[ -r "$CONF" ] && . "$CONF"
|
||
|
|
VIP="${VRRP_WAN_VIP:-192.168.1.1}"
|
||
|
|
LEASE_TTL="${LEASE_TTL:-75}"
|
||
|
|
STATE=/run/vrrp-wan
|
||
|
|
|
||
|
|
revoke() {
|
||
|
|
rm -f "$STATE/may-dial"
|
||
|
|
systemctl is-active --quiet ppp@pppoe0 2>/dev/null || return 0
|
||
|
|
logger -t vrrp-wan "GUARD: $1 -- hanging up pppoe0"
|
||
|
|
systemctl stop ppp@pppoe0 2>/dev/null
|
||
|
|
}
|
||
|
|
|
||
|
|
if ! ip -4 -o addr show 2>/dev/null | grep -q " ${VIP}/"; then
|
||
|
|
revoke "does not hold ${VIP}"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Holds the VIP, so it is entitled to dial -- but only while something is
|
||
|
|
# actively renewing the lease on its behalf.
|
||
|
|
if [ -f "$STATE/may-dial" ]; then
|
||
|
|
age=$(( $(date +%s) - $(stat -c %Y "$STATE/may-dial" 2>/dev/null || echo 0) ))
|
||
|
|
[ "$age" -gt "$LEASE_TTL" ] && revoke "lease stale (${age}s > ${LEASE_TTL}s; is vrrp-wan-reconcile.timer running?)"
|
||
|
|
fi
|
||
|
|
exit 0
|