I run quite a few computers at home (too many, don't ask). Some of these are servers that I want to have a reliable internet connection, even when I'm not at home for some time. For this reason, I set up two redundant upstream gateway routers, and used ucarp to manage the automatic failover. Ucarp is a portable implementation of CARP (Common Address Redundancy Protocol). At the time, this seemed like a fairly simple and straightforward tool for the job. Unfortunately, after some time I found that it wasn't always 100% reliable, so I started looking for alternatives. I found that the selection was somewhat limited. There were some abandonware tools that hadn't been maintained for a while, some tools that only work in combination with a full Quagga router setup, etc, but nothing that was current, fully functional, and reasonably simple to set up.
So I set about to write my own. I mean, what else would you do?
My goal was to make something that is relatively simple, has relatively few external dependencies, and is preferably portable to other UNIX systems, such at *BSD, even though I develop mostly on Devuan/Debian these days.
The implementation of the core functionality is necessarily kinda tricky, as you are working on raw IP packets, not TCP or UDP, with even a bit of Ethernet MAC frame magic thrown in for good measure, and that automatically gets you into the slightly murkier parts of the socket interfaces on most systems. Still, for the most part, there is enough commonality among systems that I think most of the raw socket code can be considered reasonably portable.
Things are a bit different for the manipulation of the state of the interface that will present itself as the default gateway interface to the network, as this involves manipulating Ethernet MAC addresses. I took the cheap route out of this problem, by outsourcing this functionality to a few shell scripts that can be considered part of the configuration, and may be different depending on operating system details.
On my Linux systems, these scripts contain a few basic ip(8) commands to manipulate a macvlan device.
One nice aspect of RFC 5798 is that you can basically just go through the spec bit by bit, and translate the description into a corresponding bit of code. So a good part of my code has direct references to the exact section of the standard document that it implements.
After a few weeks I had something working and installed it on my routers. The whole thing is less that 40k of code, less than 1500 lines. It has been running for 2 years now, handled multiple failovers, restarts, and reconfigurations, and hasn't given me any trouble. I call that "good enough".
The result is called wrrpd, a minimalist implementation of the Virtual Router Redundancy Protocol, Version 3, for IPv4 and IPv6 (RFC5798).
It works, obviously, but I haven't gotten around to any of the final cleanup of the code that I had planned, meaning I wouldn't know if it comes even close to compiling on, say, a FreeBSD system, so I don't feel comfortable yet putting it up for public view. I should probably do something about that, as I already had some requests to please make it available.
Update:
Guess what? FreeBSD taught me that the IP6 socket interfaces I had found are actually not the interfaces that the IETF ultimately settled on. Fortunately, it looks like what FreeBSD implemented is also available on Linux, so a good part of the code should remain reasonably portable after I switch to the right socket APIs. Some work to be done. And then I need to figure out how to do the MAC magic that VRRP wants on FreeBSD, and run some tests.