Forcing CARP failover using pfSense
Anything that has a master/slave cluster should have some sort of mechanism for failing from the master to the slave, right? We’ll see…
pfSense provides HA via OpenBSD’s (very excellent) CARP. Of course I could just increment the advskew on all of the interfaces to fail them over individually, but that doesn’t really work for me. That involves spending some amount of time in a partially failed-over state. Having quite a bit of experience with OpenBSD, I expected there to be a more elegant solution and I certainly wasn’t disappointed. It looks like OpenBSD provides interface groups and a setting called “carpdemote”. Incrementing carpdemote on the master’s “carp” group would cause all carp interfaces to fail over to the next-in-line. nice.
I guess I was just expecting FreeBSD to have the same functionality. FreeBSD 7.0 does have interface groups, but I can’t find carpdemote in the documentation. Still, maybe pfSense 1.2.1 will be worth the upgrade afterall.
All-in-all, forcing the failover one at a time wasn’t so bad. Upping the advskew on all interfaces to 200 from a shell loop like the following got the job done, but that race condition just doesn’t sit well.
for i in 0 1 2 3; do ifconfig carp$i advskew 200 done
Then I did my work and rebooted the master. When the master came up, all of the interfaces were reset to an advskew of 0, which is less-than-ideal-but-still-expected. Strangely, this didn’t cause the interfaces to fail back to the master. For about 5 minutes the master interfaces remained BACKUP even though the master interfaces had an advskew of 0 and the backup had an advskew of 100.
After about 5 minutes all of the interfaces failed back to the master. I expect this is just a relic of how the advskew parameter actually works by tuning carp announcement intervals.