CARP (IPv4 and IPv6) in FreeBSD 10+ (for failover IPs)

Here’s how to configure CARP (common address redundancy protocol) to failover between two machines for both IPv4 and IPv6 IPs.  This requires FreeBSD 10+.

NOTE: Your switch requires you to allow multicast and IGMP.  Most switches do this, but VMware virtual switches generally do not unless you disable all security on them (not advised) – FreeBSD bhyve VMs work fine so long as the host’s upstream switch supports it.

We have a machine that should normally be the master of the pair.  It has non-shared IPs of 192.0.2.101/24 and 2001:db8::101/64

We have a machine that should normally be the slave of the pair.  It has non-shared IPs of 192.0.2.102/24 and 2001:db8::102/64

The two machines will share the IPs 192.0.2.1 and 2001:db8::1 – the master will respond to these IPs, and the slave will take over if the master disappears.  This ordinarily happens in under a second.  A few packets are lost during the failover but TCP retransmits etc take care of this and it is usually unnoticable.

Each CARP setup requires a VHID (this determines the MAC address used so it should be unique on the network) and a password to protect announcements.  We’ll use VHID 1 for the IPv4 setup and VHID 2 for the IPv6 setup.  We will use a password of testpass for demonstration purposes.

The only difference between the two machine setups is the advskew value.  This decides the priority of each machine.  The lower the number, the higher the priority.  The master will be the machine with the lowest advskew

First, we need to load the kernel module on each machine.  In /boot/loader.conf add:

carp_load=”YES”

Now we need to add the network configuration.  Setup the server as normal with its static IPs, then we can add additional IPs to the network card for the CARP configuration.  In our example, we are using the network interface vtnet0 (a bhyve vm).

Add the following lines (modified for your use) to /etc/rc.conf:

ifconfig_vtnet0_alias0=”inet 192.0.2.1/24 vhid 1 advskew 100 pass testpass”
ifconfig_vtnet0_alias1=”inet6 2001:db8::1 prefixlen 64 vhid 2 advskew 100 pass testpass”

As mentioned before, setup the slave machine identically except the two above lines would have advskew 200 to ensure they are lower priority.

Reboot the machines and login to check with ifconfig vtnet0 command.

Here’s the output on the master machine:

vtnet0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=80028<VLAN_MTU,JUMBO_MTU,LINKSTATE>
ether 58:9c:fc:05:c4:0d
inet6 fe80::5a9c:fcff:fe05:c40d%vtnet0 prefixlen 64 scopeid 0x1
inet 192.0.2.1 netmask 0xffffff00 broadcast 192.0.2.255 vhid 1
inet6 2001:db8::1 prefixlen 64 vhid 2
inet6 2001:db8::101 prefixlen 64
inet 192.0.2.101 netmask 0xffffff00 broadcast 192.0.2.255
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
media: Ethernet 10Gbase-T <full-duplex>
status: active
carp: MASTER vhid 1 advbase 1 advskew 100
carp: MASTER vhid 2 advbase 1 advskew 100

You can see at the bottom of the output, the carp status shows that the machine is in MASTER state.

Here’s the output on the slave machine:

vtnet0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=80028<VLAN_MTU,JUMBO_MTU,LINKSTATE>
ether 58:9c:fc:04:48:35
inet6 fe80::5a9c:fcff:fe04:4835%vtnet0 prefixlen 64 scopeid 0x1
inet 192.0.2.1 netmask 0xffffff00 broadcast 192.0.2.255 vhid 1
inet6 2001:db8::1 prefixlen 64 vhid 2
inet6 2001:db8::102 prefixlen 64
inet 192.0.2.102 netmask 0xffffff00 broadcast 192.0.2.255
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
media: Ethernet 10Gbase-T <full-duplex>
status: active
carp: BACKUP vhid 1 advbase 1 advskew 200
carp: BACKUP vhid 2 advbase 1 advskew 200

Here you can see the carp status is BACKUP.

If you were to shutdown or reboot the master machine, the slave machine would change to MASTER status.

This is also logged into /var/log/messages:

Jun  5 22:34:51 carp-slave kernel: carp: VHID 1@vtnet0: BACKUP -> MASTER (master down)
Jun  5 22:34:51 carp-slave kernel: carp: VHID 2@vtnet0: BACKUP -> MASTER (master down)

It’s also possible to monitor this and trigger a script upon changes using devd – but that is out of scope for this article.  If there’s enough interest, I might do a further article.

Leave a Reply

Your e-mail address will not be published. Required fields are marked *