DHCPv6 Failover Protocol
Extracted elements (27)
The DHCPv6 failover protocol defines an active-passive (hot standby) model rather than active-active: during normal operation the primary server handles client traffic while the secondary maintains a copy of the binding database and responds only to requests directed specifically to it. This design simplifies consistency guarantees and avoids split-brain address allocation conflicts.
The lazy update mechanism allows a server to respond to a DHCP client immediately after allocating or extending a lease, deferring the synchronization BNDUPD message to its partner until time permits. This satisfies the RFC 7031 requirement that failover must not introduce significant performance impact on server response times, at the cost of a bounded window of inconsistency bounded by MCLT.
The failover message format is compatible with the standard DHCPv6 message format (RFC 3315, Section 6) and reuses the TCP framing defined in DHCPv6 Bulk Leasequery (RFC 5460, Section 5.1). Options used in failover messages are drawn from the same DHCPv6 Option Codes registry, requiring coordination with existing DHCPv6 option assignments.
A server MUST NOT send a BNDREPLY message in response to a BNDUPD message until it is certain that the binding information from the BNDUPD has been written to stable storage. This ensures the acknowledging server has durably recorded the partner lifetime before the sending server relies on that acknowledgement.
Every primary server MUST periodically attempt to create a TCP connection to port 647 of all configured partners, and MUST continue attempting to connect even after rejection. Every secondary server MUST listen for TCP connection attempts on port 647. The primary always initiates connections and sends the CONNECT message; the secondary responds with CONNECTREPLY.
For independent allocation, the primary server MUST allocate only IPv6 addresses where bit 127 equals 1, and the secondary server MUST allocate only IPv6 addresses where bit 127 equals 0.
The CONTACT message MUST be transmitted periodically over every established connection if other message traffic is not flowing, to ensure the partner continues to see the connection as operational. The keepalive interval is negotiated via OPTION_F_KEEPALIVE_TIME (code 128).
The DHCPv6 failover protocol MUST NOT be used for new leases shorter than 30 seconds, because the lazy-update and MCLT mechanisms are not designed for such short lifetimes. Leases already approaching expiration are not subject to this restriction.
The transaction-id in a failover message MUST be unique among all currently outstanding messages sent to the failover partner. Implementors must take care that long-outstanding UPDREQ or UPDREQALL transaction-ids are not duplicated by subsequent messages before the corresponding UPDDONE is received, since the 24-bit transaction-id can wrap.
When in PARTNER-DOWN state, a server MUST allocate new leases only from its own pool and MUST NOT use its partner's pool for new IPv6 address leases. During COMMUNICATIONS-INTERRUPTED, an operational partner MAY extend existing address leases but MUST NOT lease addresses that were assigned to its downed partner and later expired or were released.
DNS update coordination: when a server updates DNS on behalf of a client, it records the hostname, zone name, and update flags in OPTION_F_DNS_REMOVAL_INFO (code 116), which encapsulates OPTION_F_DNS_HOST_NAME (117), OPTION_F_DNS_ZONE_NAME (118), and OPTION_F_DNS_FLAGS (119). This allows the partner or a taking-over server to remove DNS records created by the original server.
Independent allocation is used for IPv6 address leases: available addresses are permanently split between the primary and secondary servers based on the low-order bit (bit 127) of the address. The primary allocates addresses where bit 127 = 1; the secondary allocates where bit 127 = 0. No message exchange is required to distribute this allocation.
Proportional allocation is used for delegable prefix leases: the primary owns all available delegable prefixes initially and distributes a configured proportion to the secondary via BNDUPD messages with state FREE-BACKUP. The secondary triggers rebalancing by sending POOLREQ; the primary responds with POOLRESP and then sends prefix leases via BNDUPD.
The CONNECT/CONNECTREPLY handshake exchanges critical configuration attributes including OPTION_F_MCLT, OPTION_F_RELATIONSHIP_NAME, OPTION_F_PROTOCOL_VERSION, OPTION_F_MAX_UNACKED_BNDUPD, and OPTION_F_CONNECT_FLAGS (including the FIXED_PD_LENGTH bit). After a successful exchange, the first message sent is a STATE message; receipt of the STATE message establishes communications as 'OK'.
The Maximum Client Lead Time (MCLT) is a configured interval that bounds the difference between the valid lifetime given to a DHCP client and the lifetime known by the partner server. The fundamental relationship is: lease expiration time given to a client MUST NOT exceed the later of the partner's acknowledged partner lifetime or the current time by more than the MCLT.
Twelve message types are defined for failover communication: BNDUPD (24), BNDREPLY (25), POOLREQ (26), POOLRESP (27), UPDREQ (28), UPDREQALL (29), UPDDONE (30), CONNECT (31), CONNECTREPLY (32), DISCONNECT (33), STATE (34), and CONTACT (35). All failover traffic is carried over a long-lived TCP connection on port 647.
RFC 8156 adds new DHCPv6 message types to the 'Message Types' sub-registry: BNDUPD (24), BNDREPLY (25), POOLREQ (26), POOLRESP (27), UPDREQ (28), UPDREQALL (29), UPDDONE (30), CONNECT (31), CONNECTREPLY (32), DISCONNECT (33), STATE (34), and CONTACT (35).
RFC 8156 adds new DHCPv6 option codes to the 'Option Codes' sub-registry of the DHCPv6 registry: OPTION_F_BINDING_STATUS (114) through OPTION_F_STATE_EXPIRATION_TIME (134), a total of 21 new option codes for failover use.
RFC 8156 adds new DHCPv6 status codes to the 'Status Codes' sub-registry: AddressInUse (16), ConfigurationConflict (17), MissingBindingInformation (18), OutdatedBindingInformation (19), ServerShuttingDown (20), DNSUpdateNotSupported (21), and ExcessiveTimeSkew (22).
A server detects excessive time skew by comparing its current time with the sent-time field of received messages; if the skew exceeds 5 seconds, it SHOULD respond with the ExcessiveTimeSkew (22) status code and SHOULD close the connection. Time skew can indicate clock misconfiguration or a man-in-the-middle attack replaying old messages.
The failover protocol carries sensitive binding information and must be protected. The TCP connection between failover partners SHOULD be secured using TLS as defined for DHCPv6 Bulk Leasequery (RFC 7653), which provides mutual authentication and confidentiality. An unauthenticated or unencrypted failover channel allows an attacker to inject false binding updates, redirect clients, or disrupt service.
A failover endpoint transitions through the following states: STARTUP (initial, indicated via flag not STATE message) → NORMAL (both servers healthy) → COMMUNICATIONS-INTERRUPTED (link lost) → PARTNER-DOWN (partner confirmed down, manual or auto) → RECOVER (partner reconnects and requests full sync) → RECOVER-WAIT (sync complete, waiting MCLT) → RECOVER-DONE (interlock before NORMAL). Additional states: POTENTIAL-CONFLICT, RESOLUTION-INTERRUPTED, and CONFLICT-DONE handle binding conflicts during resynchronization.
All failover messages share a common fixed-size header followed by variable-length options: msg-type (1 octet), transaction-id (3 octets), sent-time (4 octets, unsigned 32-bit, seconds since 2000-01-01 UTC modulo 2^32), and options (variable). All values are in network byte order.
OPTION_F_BINDING_STATUS (option code 114, option-len 1) carries a 1-octet unsigned binding-status value encoding the lease state: 1=ACTIVE, 2=EXPIRED, 3=RELEASED, 4=PENDING-FREE, 5=FREE, 6=FREE-BACKUP, 7=ABANDONED, 8=RESET.
OPTION_F_MCLT (option code 122, option-len 4) carries the Maximum Client Lead Time as an unsigned 32-bit integer in network byte order, representing seconds. OPTION_F_PARTNER_LIFETIME (code 123, option-len 4) and OPTION_F_EXPIRATION_TIME (code 120, option-len 4) carry absolute times as unsigned 32-bit integers (seconds since 2000-01-01 UTC modulo 2^32).
OPTION_F_PROTOCOL_VERSION (option code 127, option-len 4) encodes two unsigned 16-bit integers in network byte order: major-version (initially 1) and minor-version (initially 0), allowing partners to negotiate protocol compatibility across future revisions.
OPTION_F_SERVER_STATE (option code 132, option-len 1) encodes the sender's failover endpoint state as a 1-octet value (1=STARTUP through 10=CONFLICT-DONE). OPTION_F_SERVER_FLAGS (code 131, option-len 1) carries flag bits including STARTUP (bit 6), ACK_STARTUP (bit 5), and COMMUNICATED (bit 7).