Common Address Redundancy Protocol
The Common Address Redundancy Protocol (CARP) is a computer networking protocol that enables multiple hosts on the same local area network to share a set of IP addresses, ensuring high availability and failover by designating one host as the master to handle traffic while backups monitor and take over if the master fails.[1] Developed as an open-source alternative to the patented VRRP and the proprietary HSRP, CARP was first introduced in OpenBSD 3.5 in 2004 and has since been implemented in various BSD-derived systems, including FreeBSD, NetBSD, and pfSense firewalls.[2][3]
CARP operates by assigning a unique Virtual Host ID (VHID) to each redundancy group, with hosts configured to advertise their availability at intervals determined by the advbase (base advertisement interval in seconds) and advskew (skew to prioritize the master) parameters.[1] The master host sends periodic multicast or unicast advertisements; if backups detect the absence of these (typically after three missed heartbeats), the backup with the lowest skew assumes the master role, transparently redirecting traffic to the shared IP addresses without interrupting services.[2] This mechanism supports both IPv4 and IPv6, and includes security features like HMAC-SHA1 authentication using a shared passphrase to prevent unauthorized takeovers.[3]
Beyond basic failover, CARP provides load balancing capabilities by distributing traffic across multiple active masters in a group, configurable via the carpnodes option (e.g., specifying weights for IP hashing).[1] It attaches as a pseudo-device to physical interfaces and can operate in modes such as IP multicast (default), unicast for restricted networks, or stealth to hide the virtual MAC address, making it versatile for scenarios like redundant firewalls or web servers.[1] Global behaviors, including preemption (where a higher-priority host reclaims mastery) and logging of state changes, are tunable via sysctl parameters.[1] Overall, CARP's design emphasizes simplicity, security, and no licensing costs, distinguishing it from standards like RFC 3768 for VRRP by offering enhanced protection against spoofing.[3]
Overview
Definition and Purpose
The Common Address Redundancy Protocol (CARP) is an open protocol that enables multiple hosts on the same local network segment to share a set of IPv4 and/or IPv6 addresses.[4][1] Developed as a free alternative to proprietary redundancy protocols, CARP assigns these shared addresses to redundancy groups identified by a Virtual Host ID (VHID), allowing only one host to actively use them at a time while others remain in standby.[5] This mechanism ensures that the shared addresses appear as a single, stable endpoint to the network, facilitating high availability without requiring modifications to client configurations.[6]
The primary purpose of CARP is to provide redundancy for critical network services, such as default gateways or firewalls, by enabling seamless failover in the event of a host failure.[3] When the active (master) host stops sending periodic advertisements, a backup host automatically assumes the role and takes over the shared addresses, minimizing service disruptions and ensuring continuous operation.[4] This failover process is particularly valuable in environments requiring uninterrupted connectivity, such as enterprise networks or perimeter defenses, where downtime could compromise security or accessibility.[1]
Key benefits of CARP include enhanced continuous availability, protection against single points of failure, and support for load distribution. By eliminating reliance on a single host, CARP safeguards against hardware failures, network issues, or maintenance events, which is essential for stateful firewalls that maintain connection tracking. Load distribution is achieved through hashing mechanisms on IP addresses (source, destination, and optionally ports) across multiple CARP groups sharing the same virtual IP but using distinct VHIDs, ensuring consistent traffic routing to the same host for related connections. This approach not only balances traffic but also improves overall network resilience without introducing bottlenecks.[3]
CARP operates at the network layer (Layer 3) as an IP protocol with number 112, utilizing multicast advertisements to 224.0.0.18 (IPv4) or FF02::12 (IPv6) for master election and status updates among group members.[1] These advertisements, sent at configurable intervals, allow hosts to monitor each other and trigger elections transparently, supporting both failover and balanced operation across compatible systems like those in the BSD family.[4]
Basic Principles of Redundancy
The Common Address Redundancy Protocol (CARP) operates on the principle that multiple hosts on the same local network segment can form a redundancy group to share a virtual IP address (VIP), ensuring continuous availability of network services. In this setup, one host serves as the master, actively responding to traffic directed at the VIP, while the others function as backups that remain idle until needed. This shared addressing mechanism allows for seamless traffic handling without requiring changes to client configurations, as the VIP remains constant regardless of which host is active.[1][9]
The failover process in CARP relies on periodic status advertisements sent by the master host to the group members. These advertisements occur at configurable intervals, and backups monitor for their presence; if the master fails and advertisements cease, the backups detect the absence within a short timeout period. A new master is then elected based on priority, typically determined by a skew value where the host with the highest priority (lowest skew) assumes the role, promoting rapid transition to minimize service interruption. This election ensures that the group self-heals automatically without external intervention.[1][6][9]
To enhance redundancy beyond simple failover, CARP supports optional load sharing through hashing of source and destination IP addresses (and optionally ports), which distributes incoming traffic across multiple active hosts in the group for balanced utilization. This is achieved by configuring multiple CARP subgroups sharing the same VIP, where the hash determines which subgroup—and thus which host—processes each packet. The Virtual Host ID (VHID) plays a crucial role here, serving as a unique identifier for each redundancy group on a given network interface, allowing multiple independent groups to coexist without interference.[1][6][9]
Overall, these principles provide significant advantages, including downtime reduction to mere seconds during failover, far surpassing manual intervention times, and support for both active-passive modes (single master with hot standbys) and active-active modes (concurrent load distribution). This approach delivers high availability for critical network functions like routing and firewalling, making it suitable for environments demanding uninterrupted service.[6][9]
Technical Details
Protocol Operation
In CARP, hosts sharing a Virtual Host ID (VHID) form a redundancy group to provide failover for a common virtual IP address. The election of the master host occurs through a priority-based mechanism using two parameters: the base advertisement interval (advbase, typically 1 second) and the advertisement skew (advskew, ranging from 0 to 254). The host with the lowest effective advertisement interval—calculated as advbase + (advskew / 256)—is preferred as master, as it advertises more frequently. If advskew values are equal, the election may fall to random selection among tied hosts. Upon interface failure or demotion (e.g., due to link issues), a host's advskew increases automatically by a demotion factor (default 240), reducing its priority and allowing another host to take over.[10][3][11]
The master host periodically sends multicast advertisement packets to the address 224.0.0.18 (protocol number 112, TTL 255) at intervals determined by its advbase + advskew. These packets include the VHID and are authenticated using a shared secret to prevent unauthorized participation. Backup hosts in the group listen for these advertisements; if the master fails and no packets are received for three times the expected interval (typically around 3 seconds with default settings), the backup with the next-lowest interval assumes the master role and begins advertising. Preemption is optional and configurable based on priority, allowing a higher-priority host to reclaim the master state upon recovery.[3][10]
CARP operates through defined state transitions for each host in a group: starting in INIT (initialization, where the interface is configured but inactive), transitioning to BACKUP (monitoring advertisements without responding to traffic), and to MASTER (actively handling traffic for the virtual IP and sending advertisements). These transitions are triggered by configuration changes, advertisement receipt, or timeouts. For setups with multiple interfaces or VHID groups, each group operates independently, bound to a specific physical interface via a carpdev parameter, enabling redundancy across diverse network segments without interference.[12][3][11]
When load balancing is enabled (via sysctl parameters like net.inet.carp.arpbalance), CARP distributes incoming ARP requests across multiple hosts sharing the same virtual IP but using different VHIDs. This is achieved by computing a hash from packet details to determine which host responds:
hash = (source_IP XOR destination_IP XOR VHID) mod number_of_group_members
hash = (source_IP XOR destination_IP XOR VHID) mod number_of_group_members
If the computed hash matches the host's VHID modulo the group size, it generates the ARP reply; otherwise, it ignores the request. This ensures even traffic distribution while maintaining redundancy, with the VHID playing a key role in consistent hashing.[3]
Packet Structure and Authentication
The Common Address Redundancy Protocol (CARP) packets are encapsulated within IP datagrams using protocol number 112 for both IPv4 and IPv6. For IPv4, advertisements are sent as multicast packets with the destination address 224.0.0.18 and a time-to-live (TTL) value of 255, using the shared virtual IP address (VIP) as the source address. For IPv6, the destination is the link-local multicast address ff02::12 with a hop limit of 255, again sourcing from the shared VIP. This multicast approach ensures efficient distribution within the local network segment while preventing propagation beyond it. Packets with a TTL or hop limit not equal to 255 are silently dropped to enforce local scope.
The CARP header follows immediately after the IP header and is 36 bytes long for both IPv4 and IPv6, structured as a packed binary format without padding. The header includes fields for protocol identification, timing parameters, integrity checks, and security. The version and type fields occupy the first byte: version (4 bits, value 2) in the high nibble and type (4 bits, value 1 for advertisement) in the low nibble. The virtual host ID (VHID), an 8-bit field (values 1–255), uniquely identifies the redundancy group and determines the associated virtual MAC address (e.g., 00:00:5E:00:01:VHID for Ethernet). The advertisement skew (advskew) is an 8-bit value (0–254) that fine-tunes the advertisement interval for master/backup prioritization, while the advertisement base (advbase) is an 8-bit value (1–255) specifying the base interval in seconds. The authentication length (authlen) field, 8 bits, indicates the size of the counter and message digest (MD) in 32-bit words, typically 7 for the standard configuration ((64-bit counter + 160-bit MD) / 32 bits). A demotion counter (8 bits) tracks temporary master demotions due to interface failures, defaulting to 0.
The header's integrity is protected by a 16-bit checksum field, computed as the IP-style one's complement sum over the entire header (excluding the MD). Following the checksum are two 32-bit counters forming a 64-bit value for anti-replay protection, though implementations often increment only the low-order word. The final 20 bytes (160 bits) contain the message digest, which is the HMAC-SHA1 output computed using a pre-shared key configured on all group members.[13]
| Byte Offset | Field Name | Size (bits) | Description |
|---|
| 0 | Version (bits 7-4) + Type (bits 3-0) | 8 | Protocol version (2) and packet type (1 for advertisement). |
| 1 | VHID | 8 | Virtual Host ID (1–255). |
| 2 | Advskew | 8 | Advertisement skew (0–254). |
| 3 | Authlen | 8 | Length of counter + MD in 32-bit words (typically 7). |
| 4 | Demote | 8 | Demotion counter (0–255). |
| 5 | Advbase | 8 | Advertisement base interval in seconds (1–255). |
| 6–7 | Checksum | 16 | Ones' complement checksum of the header. |
| 8–11 | Counter (low) | 32 | Low-order anti-replay counter. |
| 12–15 | Counter (high) | 32 | High-order anti-replay counter (often 0). |
| 16–35 | MD (Auth Data) | 160 | HMAC-SHA1 message digest. |
Authentication relies on a shared secret key (up to 256 characters, but effectively used as a 512-bit key for HMAC via padding), configured identically across all hosts in the VHID group. The message digest is generated as the HMAC-SHA1 of the header fields from version through the counters (excluding checksum and MD itself), providing protection against spoofing and tampering. The digest ensures only authorized hosts can validate advertisements, with invalid digests causing silent packet drops. The checksum is verified first; failures result in immediate discard without further processing. No explicit error responses are defined, maintaining the protocol's lightweight design.[13][3]
Implementations and Use Cases
Operating System Support
CARP is natively supported in OpenBSD since version 3.5, released in May 2004, where it is tightly integrated with the PF firewall and pfsync for state synchronization across redundant hosts.[14][4] This integration allows seamless failover for firewall rules and connection states, making it a cornerstone for high-availability setups in OpenBSD environments.[4]
FreeBSD includes native CARP support starting from version 5.4 in 2005, following a port from OpenBSD in 2004, and it is extensively used in firewall distributions like pfSense.[11][12] pfSense, built on FreeBSD, leverages CARP for redundant gateways and load balancing, with added features such as IPv6 compatibility and the ability to assign multiple Virtual Host IDs (VHIDs) per interface for granular control.[2][11]
NetBSD has supported CARP since version 4.0, released in December 2007, with integration similar to OpenBSD's PF for firewall redundancy.[3] This enables shared IP addresses across hosts on the same network segment, ensuring continuous availability during failures.[15] DragonFly BSD provides native CARP support, imported around 2007.[16]
Support in other operating systems is more limited. Linux lacks native kernel-level CARP implementation and relies on user-space tools like UCARP for compatibility, which provides a portable but less integrated alternative.[17] Windows does not offer native CARP support, requiring third-party software for similar redundancy functions.[18] Certain Cisco Nexus switches include CARP compatibility for virtual Ethernet interfaces in data center environments.[19]
CARP is commonly paired with pfsync in BSD systems to synchronize firewall states between active and backup nodes, enhancing failover reliability.[4] It also integrates well with IPsec for securing redundancy tunnels in distributed setups.[4] However, its absence from the mainline Linux kernel necessitates user-space daemons, which may introduce additional latency compared to native BSD implementations.[17]
Basic OpenBSD Configuration
In OpenBSD, CARP interfaces are configured using the ifconfig command, typically in /etc/hostname.carp0 or via manual invocation after creating the interface. To set up a basic CARP interface on the master host, execute ifconfig carp0 create followed by ifconfig carp0 vhid 1 pass secretkey advskew 0 192.168.1.1 netmask 255.255.255.0, where vhid 1 assigns the virtual host identifier, pass secretkey sets the authentication passphrase, advskew 0 ensures priority as master (lower skew value), and the IP address is the shared virtual IP.[4] On the backup host, use the same command but with advskew 100 to lower its priority, preventing it from advertising unless the master fails.[4] To allow CARP protocol traffic (protocol number 112), add PF rules in /etc/pf.conf such as pass in on em0 proto carp and pass out on em0 proto carp, where em0 is the parent interface; reload PF with pfctl -f /etc/pf.conf.[4] Enable CARP system-wide by ensuring net.inet.carp.allow=1 in /etc/sysctl.conf if not already default.[4]
pfSense Configuration
pfSense, built on FreeBSD with OpenBSD's PF integration, configures CARP via the web GUI for easier management in high-availability clusters. First, assign unique static IPs to physical interfaces on both nodes (e.g., primary WAN: 198.51.100.1/24, secondary: 198.51.100.2/24) and set up a dedicated sync interface (e.g., 172.16.1.2/24 on primary, 172.16.1.3/24 on secondary).[20] Under System > High Availability Sync, enable "Synchronize States" on the sync interface, set the peer IP (e.g., 172.16.1.3 on primary), and configure XML-RPC for config sync from primary to secondary, including firewall rules and aliases.[20] For Virtual IPs, navigate to Firewall > Virtual IPs, add a new CARP-type VIP on the desired interface (e.g., LAN), specify the shared address (e.g., 192.168.1.1/24), VHID (e.g., 1), matching passphrase, advertising frequency base of 1, and skew of 0 on primary or 100 on secondary; repeat for WAN VIPs.[20] Apply changes to activate; pfsync handles state synchronization automatically once enabled.[20]
IPv6 Setup
CARP supports IPv6 alongside IPv4, using similar ifconfig parameters but with inet6 addressing. In OpenBSD, create the interface with ifconfig carp0 create, then configure ifconfig carp0 vhid 1 pass secretkey advskew 0 inet6 2001:db8::1 prefixlen 64, assigning the shared IPv6 address; on backup, add advskew 100.[1] Include PF rules like pass in on em0 proto carp from any to any to permit IPv6 CARP advertisements, as the protocol operates identically for both address families.[4] In pfSense, add IPv6 CARP VIPs via Firewall > Virtual IPs, selecting CARP type, interface, and address (e.g., 2001:db8:1::1/64 for LAN, VHID 2, skew 0/100), with link-local addresses like fe80::1%interface/64 for VHID 3 if needed for router advertisements.[20]
Troubleshooting Tips
Monitor CARP status in OpenBSD using ifconfig -g carp to view demotion counters and states (e.g., MASTER or BACKUP); a non-zero demote count indicates issues like parent interface failure.[4] Check system logs with tail -f /var/log/daemon for CARP transitions, such as "carp: BACKUP -> MASTER" on failover, and ensure multicast routing is enabled (default via IGMP) since CARP uses 224.0.0.18 for IPv4 advertisements.[4] In pfSense, view CARP status under Status > CARP (CARP Status) for master/backup indicators per VIP, and use Diagnostics > States for sync verification; logs under Status > System Logs > Firewall filter demotions if skew misconfiguration causes flapping.[21] Verify passphrase and VHID match across nodes, as mismatches prevent synchronization.[20]
Advanced Configurations
For multiple CARP groups on one interface in OpenBSD, create additional interfaces like ifconfig carp1 create and ifconfig carp2 create, then assign them to a group with ifconfig carp1 group internal and ifconfig carp2 group internal to link demotions (e.g., if one fails, the group preempts).[4] Load balancing can be achieved in active/active setups by configuring pfsync with ifconfig pfsync0 syncdev em1 up and using defer mode in /etc/hostname.pfsync0 to avoid state conflicts, distributing traffic via CARP's hash-based advertisement selection.[4] In pfSense, multiple VIPs share VHIDs per interface (e.g., VHID 1 for LAN IPv4, 2 for IPv6), with group syncing handled automatically through the HA config.[20]
Sample Network Diagram
A basic two-host failover setup connects two firewalls via a dedicated sync link for pfsync, with shared CARP IPs on WAN and LAN interfaces:
Internet/WAN
|
+-------------------+
| |
em2 (198.51.100.1) em2 (198.51.100.2)
| |
+-----+-----+ +-----+-----+
| Firewall1| | Firewall2|
| (Master) | em1 ---| (Backup) |
+-----+-----+ +-----+-----+
| |
em0 (192.168.1.2) em0 (192.168.1.3)
| |
+-------------------+
LAN (CARP VIP: 192.168.1.1)
Internet/WAN
|
+-------------------+
| |
em2 (198.51.100.1) em2 (198.51.100.2)
| |
+-----+-----+ +-----+-----+
| Firewall1| | Firewall2|
| (Master) | em1 ---| (Backup) |
+-----+-----+ +-----+-----+
| |
em0 (192.168.1.2) em0 (192.168.1.3)
| |
+-------------------+
LAN (CARP VIP: 192.168.1.1)
This diagram shows em1 as the crossover sync link (e.g., 172.16.1.0/24), ensuring isolated state sync while CARP handles IP failover on em0/em2.[4][20]
History and Development
Origins in OpenBSD
The development of the Common Address Redundancy Protocol (CARP) began in the early 2000s within the OpenBSD project, primarily led by Jun-ichiro "itojun" Hagino, as an open-source response to the proprietary and patented router redundancy protocols Hot Standby Router Protocol (HSRP) and Virtual Router Redundancy Protocol (VRRP), both controlled by Cisco Systems.[22] Hagino's initiative addressed the absence of free implementations of VRRP in BSD systems over five years after its RFC publication, due to patent concerns that deterred adoption.[22] The protocol was designed to provide failover and redundancy for network gateways, particularly firewalls, without infringing on existing patents, following a detailed analysis to ensure divergence from HSRP claims.[22]
Hagino presented the initial design of CARP at the 58th IETF meeting in November 2003, emphasizing simplicity, security through HMAC-SHA1 authentication for advertisements, and support for both IPv4 and IPv6.[22] This outline highlighted CARP's use of variable advertisement intervals, where the most frequent advertiser assumes the master role, and layer-2 load balancing via ARP.[22] The protocol was integrated from the outset with OpenBSD's pf packet filter, enabling seamless redundancy in stateful firewall setups to synchronize states across hosts.[23]
Implementation efforts involved additional contributors, including Mickey Shalayeff, Markus Friedl, Marco Pfatschbacher, and Ryan McBride, who refined the code for production use.[14] CARP was imported into the OpenBSD source tree on October 17, 2003, and first released in OpenBSD 3.5 on May 1, 2004, marking its debut as a secure, patent-free alternative for high-availability networking.[14][23] Early challenges included verifying non-infringement on Cisco patents—without formal assurances—and ensuring backward compatibility with existing network infrastructures while prioritizing open-source principles.[22][1]
Adoption and Evolution
Following its initial implementation in OpenBSD, CARP was ported to other BSD variants to expand its availability for high-availability networking. FreeBSD integrated CARP in version 5.4, released on May 5, 2005, enabling multiple hosts to share IP addresses for failover in enterprise environments.[24] NetBSD followed with support in version 4.0, released on December 19, 2007, providing similar redundancy features across its portable kernel.[25] The pfSense project, a FreeBSD-based firewall distribution launched in 2006, incorporated CARP from its early releases, significantly popularizing the protocol in network appliances and small-to-medium business deployments for seamless failover configurations.[26]
Over time, enhancements focused on broadening compatibility and reliability. IPv6 support was added in OpenBSD 4.0, released on November 1, 2006, allowing CARP to handle both IPv4 and IPv6 addresses as shared virtual hosts.[27] Integration with pfsync, OpenBSD's state synchronization protocol, was refined to enable stateful failover, ensuring firewall states (such as connection tracking) are mirrored between nodes during redundancy events, a feature that matured through subsequent releases in BSD derivatives.[4]
CARP's community adoption grew through contributions in BSD ecosystems, particularly for high-availability clusters where it facilitates load balancing and fault tolerance among firewalls.[28] It found use in embedded systems via FreeBSD and NetBSD ports, supporting redundant routing in resource-constrained devices like network appliances.[29] Open-source developers extended its functionality through kernel patches and documentation, fostering its role in security-oriented setups. Jun-ichiro "itojun" Hagino, a key figure in CARP's development, passed away on August 5, 2007; OpenBSD 4.2 was dedicated to his memory in recognition of his contributions to networking and IPv6.[30]
As of 2025, CARP remains stable in BSD derivatives like FreeBSD, OpenBSD, and NetBSD, with no major protocol revisions since its 2003 specification.[12] Adoption on Linux is limited, as administrators prefer the standardized VRRP due to broader interoperability and IETF backing.[31] It is widely used in security-focused networks, notably comprising the core redundancy mechanism in pfSense high-availability setups.[2]
Standards and Comparisons
Incompatibility with IETF Protocols
The Common Address Redundancy Protocol (CARP) has never been submitted to the Internet Engineering Task Force (IETF) for standardization as a Request for Comments (RFC), remaining instead an implementation-specific protocol developed primarily for BSD-derived operating systems.[4] In contrast, the IETF's Virtual Router Redundancy Protocol (VRRP) is defined in RFC 3768 as a standards-track protocol for providing redundancy in virtual router configurations.[32] CARP was intentionally designed as a BSD-centric solution, diverging from VRRP to address specific needs in open-source environments without engaging in the IETF's collaborative standardization process.[22]
Key technical incompatibilities between CARP and VRRP stem from differences in their packet formats and operational mechanics, despite sharing the same IP protocol number (112) and IPv4 multicast address (224.0.0.18).[9] CARP employs a unique structure that includes a Virtual Host ID (VHID) for group identification and SHA-1 HMAC for authentication, without any built-in compatibility mode for VRRP packets.[5] VRRP, however, uses a distinct packet layout with fields for router priority and advertisement intervals, along with optional MD5 authentication or plaintext passwords, making direct communication impossible even on shared networks.[32] These structural variances ensure that CARP advertisements are not interpretable by VRRP implementations, and vice versa, often leading tools like Wireshark to misdecode CARP traffic as VRRP by default.[4]
As a result, CARP and VRRP exhibit significant interoperability issues, preventing devices using the two protocols from participating in the same redundancy group.[5] Network administrators must deploy either all-CARP or all-VRRP configurations within a given broadcast domain to avoid failures in failover detection or election processes; mixing them can cause packet drops, election loops, or complete redundancy breakdown.[9] This limitation confines CARP primarily to environments with uniform BSD-based support, such as OpenBSD, FreeBSD, and NetBSD, while VRRP enjoys broader vendor adoption across commercial routers and operating systems.[4]
The primary reason for CARP's avoidance of IETF standardization was to circumvent patent concerns associated with VRRP, which Cisco Systems claimed was covered under its Hot Standby Router Protocol (HSRP) patents (e.g., U.S. Patent 5,473,599).[22] OpenBSD developers opted for a rapid, independent development path to create a fully patent-free alternative, bypassing the IETF's requirement for reasonable and non-discriminatory (RAND) licensing disclosures that could impose legal risks on free software projects.[5] This approach enabled quick integration into open-source ecosystems but fostered a fragmented redundancy protocol landscape, where CARP's open licensing avoids vendor lock-in yet limits cross-protocol ecosystems compared to the standardized VRRP.[9]
To mitigate these incompatibilities, administrators can isolate CARP and VRRP groups using separate VLANs or subnets, ensuring no overlap in multicast domains.[4] Protocol translators or gateways to bridge CARP and VRRP are theoretically possible but rarely implemented due to complexity and lack of demand; no official attempts have been made to submit CARP for IETF adoption or harmonization with VRRP.[5]
Key Differences from VRRP
The Common Address Redundancy Protocol (CARP) and the Virtual Router Redundancy Protocol (VRRP) both provide first-hop redundancy for IP networks, but CARP's design emphasizes openness, security, and flexibility to address limitations in VRRP, particularly its historical ties to proprietary influences. Developed by the OpenBSD project to avoid patent encumbrances associated with VRRP—stemming from Cisco's earlier claims on similar technologies like HSRP—CARP is released under the BSD license, enabling free implementation without licensing fees or restrictions.[33] In contrast, while VRRP is an IETF standard (RFC 5798), its evolution was influenced by Cisco's Hot Standby Router Protocol (HSRP), leading to initial patent concerns that prompted alternatives like CARP.[34] This openness in CARP facilitates broader adoption in open-source environments, such as firewalls and routers in BSD-based systems.[9]
A core difference lies in their election mechanisms for selecting the master router. CARP employs a time-based election using an advertisement base interval (default 1 second) adjusted by a skew value (0-255, in 0.01-second increments), allowing fine-grained control over failover timing and enabling backups to preempt via lower skew adjustments.[10] For instance, a node with skew 0 advertises every second, while one with skew 100 advertises every 1.1 seconds, making the former the preferred master. VRRP, however, uses a fixed priority field (1-255), where the highest priority wins election, with 255 reserved for the IP address owner and 100 as the default for backups; this provides less granular timing control.[35] CARP's approach supports more precise load distribution and preemption without explicit configuration changes.[9]
Authentication in CARP is mandatory and robust, utilizing HMAC-SHA1 (160-bit key) to cryptographically verify advertisement packets, enhancing security against spoofing in untrusted networks.[10] VRRPv3 removes authentication entirely for simplicity and security reasons, relying on IPsec for protection if needed, while earlier versions (v2) offered optional plain-text passwords or HMAC-MD5 (128-bit).[36] This mandatory strong authentication in CARP reflects OpenBSD's security focus, making it unsuitable for mixing with unauthenticated VRRP implementations.[9]
Both CARP and VRRP support multiple groups (VHIDs for CARP, VRIDs for VRRP) on a single interface, allowing diverse traffic handling without separate physical or subinterfaces.[10][34] For preemption, CARP enables it via the net.inet.carp.preempt sysctl (default disabled), often tuned with skew for controlled takeovers.[10] VRRP supports configurable preemption (default enabled), where higher-priority routers can immediately assume mastery upon recovery.[37]
Load sharing distinguishes CARP further, with built-in IP hashing via the arpbalance feature and carpnodes configuration, distributing ARP replies across nodes based on client IP for active-active balancing without additional protocols.[10] VRRP primarily focuses on active-passive failover and requires multiple VRIDs or vendor extensions (e.g., GLBP-like) for load distribution.[38] Both protocols support IPv6 natively—CARP since inception and VRRPv3 explicitly—but CARP's design integrates it seamlessly across VHIDs.[9][39]
| Feature | CARP | VRRP (v3, RFC 5798) |
|---|
| Election Method | Time-based (advbase + advskew, 0-255 for fine control) | Priority-based (1-255, fixed values) |
| Authentication | Mandatory HMAC-SHA1 (160-bit) | None (IPsec optional); v2 had optional MD5/plain-text |
| Groups per Interface | Multiple VHIDs natively | Multiple VRIDs possible on one interface |
| Preemption | Configurable via sysctl (default disabled); skew-enabled | Configurable (default enabled) |
| Load Sharing | Built-in IP hash (arpbalance) for active-active | Requires multiple groups/extensions; active-passive focus |
| Openness | BSD license, patent-free | IETF standard, historical Cisco patent influences |
| IPv6 Support | Native from start | Native in v3 |