HA + Track Interface + CARP RA source: BACKUP node still starts radvd and advertises ::/64
-
Environment
pfSense Plus 26.07
Two-node CARP HA pair
PPPoE WAN with DHCPv6 Prefix Delegation
LAN interfaces use IPv6 Configuration Type = Track Interface
Router Advertisements use a link-local CARP VIP as RA source, e.g. fe80::9:1
Additional ULA /64 is configured under RA SubnetsOnly the CARP MASTER establishes a PPPoE connection in my environment. On the BACKUP node PPPoE is intentionally disabled, so that node has no delegated IPv6 prefix. This is done through my custom package mentioned in this thread
Expected behavior
When the configured RA source CARP VIP is in BACKUP state, the node should not advertise itself as an IPv6 router on that interface.
This appears to be the intended behavior of the CARP-aware RA handling: the MASTER should advertise using the shared CARP link-local address, while the BACKUP should remain silent.
Actual behavior
On the MASTER, the generated configuration is correct:
interface vtnet0.9 { AdvSendAdvert on; AdvRASrcAddress { fe80::9:1; }; prefix 2a11:....::/64 { ... }; prefix fd6f:6e32:6465:8009::/64 { ... }; };On the BACKUP node, since no DHCPv6-PD is available, pfSense generates a second/automatic Track Interface RA configuration instead:
# Generated config for dhcp6 delegation from wan on lan interface vtnet0.9 { AdvSendAdvert on; ... prefix ::/64 { AdvOnLink on; AdvAutonomous on; }; };radvd is running on the BACKUP node and actively sends RAs from the node's physical link-local address, not the CARP VIP:
fe80::be24:11ff:fe1d:89fb > ff02::1: ICMP6, router advertisementClients consequently learn two default routers:
::/0 via fe80::9:1 # CARP / MASTER ::/0 via fe80::be24:11ff:fe1d:89fb # physical address of BACKUPThis causes intermittent IPv6 connectivity because the BACKUP node does not have an active WAN/PD.
Stopping radvd manually on the BACKUP immediately fixes the problem and clients only use the CARP router.
Possible cause
Looking at the RA generation logic, there appear to be two relevant paths:
normal/manual RA configuration, which respects the configured RA VIP/CARP state;
automatic RA generation for IPv6 Track Interface interfaces.The second Track Interface path appears to recreate an RA interface even though the configured RA source VIP is currently CARP BACKUP.
If the tracked IPv6 address does not exist, that path also appears to fall back to:
prefix ::/64This effectively bypasses the CARP-aware RA suppression performed by the normal RA configuration path.
Suggested fix
The Track Interface RA generation path should apply the same RA-source/CARP-state check as the normal RA path.
Conceptually, before generating automatic RA configuration for a tracked interface:
$raconf = config_get_path("dhcpdv6/{$if}", []); if (!empty($raconf['rainterface']) && str_starts_with($raconf['rainterface'], '_vip') && get_carp_interface_status($raconf['rainterface']) != 'MASTER') { continue; }Exact function/config names may differ, but the intent would be:
If an RA source VIP is configured and that VIP is not MASTER on this node, do not add the Track Interface to radvd.conf.
If no other interface requires radvd, the daemon can then remain stopped on the BACKUP node.
I would also question whether generating prefix ::/64 when a tracked interface currently has no delegated prefix is desirable at all. Skipping that prefix until PD becomes available seems safer.
Reproduction
Configure an HA pair.
WAN uses PPPoE + DHCPv6-PD.
LAN uses IPv6 Track Interface.
Configure a link-local CARP VIP as the RA source.
MASTER has active PPPoE/PD.
BACKUP has no active PPPoE/PD.
Inspect /var/etc/radvd.conf and capture RAs on the BACKUP LAN.The BACKUP generates prefix ::/64, starts radvd, and sends RAs using its physical link-local address.
I can provide additional configuration snippets or packet captures if useful.
-
I created a patch to fix the issue. Testing the patch in my environment currently and so far it looks very promsing:
radvd on backup node is stopped and started once in transitions to primary.
here is the patch:
--- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -379,6 +379,21 @@ continue; } + /* Honor the RA Interface (CARP VIP) setting for tracked interfaces. + * Mirrors the check performed for manually configured RA interfaces + * above: when RAs are sourced from a CARP VIP, only the MASTER node + * may advertise. Without this a BACKUP node keeps sending RAs, often + * announcing a bogus "prefix ::/64" because no prefix is delegated. + * An empty status means the VIP could not be resolved; treat that as + * non-CARP and continue, matching the manual RA code path. */ + $ratrackif = config_get_path("dhcpdv6/{$if}/rainterface"); + if (!empty($ratrackif) && strstr($ratrackif, "_vip")) { + $carpstatus = get_carp_interface_status($ratrackif); + if (($carpstatus == "BACKUP") || ($carpstatus == "INIT")) { + continue; + } + } + $realif = get_real_interface($if, "inet6"); /* prevent duplicate entries, manual overrides */@stephenw10 would that be something which can make it into the main source code? currently i am running this patch via the system patches package.
Thanks
Privacy Policy · Cookie Policy