Simple IPv4 Link-Local Addressing

This document describes how to add support for IPv4 Link-Local Addressing to an existing IPv4 DHCP client quickly and easily.

Some developers making low-cost network hardware products implement DNS-Based Service Discovery and Multicast DNS because the benefits are clear and obvious, but skip IPv4 link-local addressing, because, “It doesn’t do anything that you can’t already do with a DHCP server.” They may say, “In our target market there will always be an IPv4 DHCP server on the network.” This faulty logic stems from two factors: underestimating the benefit of link-local addressing, and overestimating the difficulty of implementing it.

The Benefit

If you use an Ethernet cable to connect two devices, then if the devices don’t implement link-local addressing (assuming instead that there will always be a DHCP server on every network) then you end up in the sad situation of having two devices that are perfectly well connected physically, perhaps at gigabit speeds, but are unable to communicate using IP due to a mere limitation of software. For many years Mac OS, Windows, and Linux have all implemented IPv4 link-local addressing, so this message is really aimed at developers making devices that connect to those computers. IPv4 and IPv6 both have link-local addressing. If a device supports IPv4, then for a good user experience it should support IPv4 link-local addressing. If a device supports IPv6, it should support IPv6 link-local addressing.

If connecting two devices with an Ethernet cable and having that work seems like an imagined scenario, consider this: it’s been real since 2002. Every network printer sold since 2002 from every major printer vendor already implements IPv4 link-local addressing and the other Zeroconf protocols (DNS-SD and mDNS). If you connect your laptop computer to a printer using an Ethernet cable, the printer just magically shows up in the print dialog (on the Mac) or in the Bonjour for Windows Printer Setup Wizard (on Windows). We shouldn’t find this surprising. We should expect this ease-of-use from all network devices. You can connect a printer to your computer with a USB cable and expect it to work. Why shouldn’t TCP/IP over Ethernet work just as easily as USB?

Similar scenarios apply with multiple devices connected to an Ethernet switch. This case also applies when there are multiple wireless devices associated with a dedicated Wi-Fi Access Point (a standalone Wi-Fi AP that’s not combined with a home gateway with DHCP and NAT). Such dedicated Wi-Fi APs are common in enterprise networks and increasingly popular in larger homes, where the customer wants multiple Wi-Fi APs for better wireless coverage, but only needs a single home gateway providing the connection to the rest of the Internet. If the home gateway is disconnected, powered off, or broken, it is useful if the rest of the devices are still able to communicate with each other locally.

One obvious important use of IP is global communication — email, web searches, on-line shopping, etc. — but that’s not the only use. The other valuable use of IP is local communication — printing on a nearby printer, controlling lights in your home, streaming music to a smart speaker, exchanging photographs and other files with people nearby, etc. If your home Internet connection is down then you won’t be able to do any global communication, but that’s no reason why local communication should fail too.

The Difficulty

Some developers do see the benefit of IPv4 link-local addressing, but imagine it will be a lot more work to implement than it really is. All of the low-cost network hardware products we’re talking about already has an IPv4 DHCP client. If you already have an IPv4 DHCP client, then enhancing it to support IPv4 link-local addressing is trivial, requiring just three small changes:

  1. After a DHCP timeout, generate a random 169.254/16 address with a 10-minute lease lifetime.
  2. If an address conflict is detected, then DHCP DECLINE for a 169.254/16 address is a no-op.
  3. At renewal time, send a new DHCP DISCOVER to check if a DHCP server has become available.

In the example implementation below, these three small pieces of additional functionality are highlighted in green, like this.

The Implementation

The example algorithm below illustrates how to enhance a legacy IPv4 DHCP client (RFC 2131) to add support for IPv4 link-local addressing (RFC 3927).

A DHCP client is not a one-shot algorithm that runs to completion and then gives a single result. Conceptually the DHCP client algorithm is something that runs continuously, adapting to changing network conditions. That doesn’t mean the DHCP client runs continuously on a separate thread, or that it is continuously consuming 100% CPU while it runs; rather it is best thought of as an event-driven state machine that responds to events like packet reception, link state changes, and timers expiring.

Event Sequence

In this document the phrase “attachment to network link” includes the device detecting that an Ethernet cable has been connected, associating with a Wi-Fi AP, roaming to a different Wi-Fi AP, etc. This includes the initial boot up of the device, but is not limited to that case. For a good user experience, a DHCP client should pay attention to hardware link state changes and respond accordingly, without forcing the user to power-cycle the device to get it to notice that a cable has been connected, or a Wi-Fi AP has come back on-line.

Upon initial boot, the interface IPv4 address is initialized to 0.0.0.0.

Upon attachment to a network link at any time, immediately after boot or later, the device goes to (1) DHCP-Discovering.

(1) DHCP-Discovering

  1. Broadcast a DHCP DISCOVER message
  2. If no DHCP OFFER after 1 second, broadcast a second DHCP DISCOVER message.
  3. If no DHCP OFFER 2 seconds after that, broadcast a third DHCP DISCOVER message.
  4. If no DHCP OFFER 4 seconds after that, instead of failing, go to (3) Self-Configuring.

If a valid DHCP OFFER is successfully received:

  1. Send a DHCP REQUEST message
  2. If no DHCP ACK after 1 second, retransmit the DHCP REQUEST message.
  3. If no DHCP ACK 2 seconds after that, retransmit the DHCP REQUEST message again.
  4. If no DHCP ACK 4 seconds after that, instead of failing, go to (3) Self-Configuring.

If a valid DHCP ACK is successfully received, continue with (2) DHCP-Configuring.

(2) DHCP-Configuring

Configure the device IPv4 address, and other appropriate parameters from the DHCP ACK message (e.g., subnet mask, recursive resolver, etc.).

Set the DHCP lease renewal timer for half of the total granted lease lifetime. Go to (4) Address Probing.

(3) Self-Configuring

If no working DHCP server appears to be responding, then instead of completely failing, the device creates its own ‘fake’ DHCP address lease.

The subnet mask in the fake DHCP lease is 255.255.0.0. There is no default gateway or DNS recursive resolver. The lifetime of the fake DHCP lease is 10 minutes. As is done for for DHCP-Configuring, the DHCP lease renewal timer is set to half of the total granted lease lifetime (i.e., 5 minutes in this case).

If the interface was already using a self-assigned (169.254/16) IPv4 link-local address, the IPv4 address in the fake DHCP lease is set to this existing address. This is to help keep addresses stable and avoid unnecessary changes. Since uniqueness of this address has already been verified, there is no need to repeat Address Probing and Announcing for this address. Go to (7) Address Maintenance.

Otherwise (the interface was previously using a DHCP-assigned IPv4 address which expired, or had no IPv4 address at all) a new IPv4 address is chosen randomly for the fake DHCP lease, with uniform distribution in the range from 169.254.1.0 to 169.254.254.255 inclusive. To check that this chosen address is unique on the local link, continue with (4) Address Probing, as for traditional DHCP.

(4) Address Probing

Regardless of whether the candidate address was DHCP-assigned or self-assigned, before the device uses the address it sends three ARP Probes to check whether this address is already in use on this network link, as described first in the original DHCP specification (RFC 2131), and later in more detail in the IPv4 Address Conflict Detection specification (RFC 5227).

If no conflicting ARP Reply is received within the probing time window, go to (6) Address Announcing.

If a conflicting ARP Reply is received within the probing time window, that means that the newly configured address is in conflict with another already in use on the network, and must not be used. Go to (5) Address Rejection.

(5) Address Rejection

If the conflicting address was DHCP-assigned, then a DHCP DECLINE message is sent to the DHCP server, as required by the DHCP specification (RFC 2131).

If the conflicting address was self-assigned (169.254/16), no DHCP DECLINE is required (or possible) since there is no DHCP server to send it to.

Reset the interface IPv4 address to 0.0.0.0 and go to (1) DHCP-Discovering to start again.

(6) Address Announcing

After successfully probing to confirm the uniqueness of the address, the device publishes its new address on the network by sending ARP Announcements (RFC 5227). This is done to clear stale data from neighboring ARP caches. The assigned IPv4 address could have been in use mere moments ago by a different device that has since departed the network, and other neighboring devices may still have that previous device’s MAC address in their ARP caches.

After announcing its new address, the DHCP client continues with (7) Address Maintenance.

(7) Address Maintenance

If, at any time, the device receives an ARP packet on an interface where the sender IP address is the IP address the host has configured for that interface, but the sender hardware address does not match the hardware address of that interface, then this is a conflicting ARP packet, indicating that another host on that link is using the same IPv4 address. If this happens, go to (5) Address Rejection.

When the lease renewal timer expires, it is time for the DHCP client to take some action:

If the existing address was self-assigned (169.254/16) go to (1) DHCP-Discovering (just like the case below, where a DHCP-assigned address lease has expired) to try again to obtain an address from a DHCP server if possible, or to continue using the existing self-assigned address if there is still no DHCP server available.

If no more time remains on the lease at all (the entire lease lifetime has expired), go to (1) DHCP-Discovering to try to obtain a new address, from a DHCP server if possible, or self-assigned if no DHCP server is responding.

Otherwise (the existing address was DHCP-assigned, and some time remains on that lease) it is time to attempt renewal of the DHCP lease. The DHCP client sends a single DHCP REQUEST message to the DHCP server to request renewal of the address lease. The DHCP client also sets its lease renewal timer appropriately:

This successive halving of the renewal timer causes the client to begin casually trying to renew its lease while plenty of time still remains, and then get increasingly aggressive with its attempts as the expiration time gets closer. For example, if the DHCP server grants a 24-hour lease, the client will attempt to renew it when 12 hours remain. If the packet is lost or the DHCP server is unreachable for some reason, the client will continue using the IP address it has been granted, and will try again to renew it when 6 hours remain. If that also fails, the client will try again when 3 hours remain, and so on, getting increasingly persistent as the time remaining to renew the lease becomes shorter.

If a valid DHCP ACK message is received from the DHCP server any time before the lease lifetime expires, the DHCP lease is updated according to the parameters in the DHCK ACK, including the lease lifetime, and the DHCP lease renewal timer is set to half of the total granted lease lifetime.

The DHCP client remains in state (7) Address Maintenance.

Conclusion

With these three simple changes, it is easy to add support for IPv4 Link-Local Addressing to an existing DHCP client.

There additional refinements that are possible in a more sophisticated DHCP client, like more nuanced handling of late conflicts (RFC 5227) or using DNAv4 (RFC 4436) for faster re-attachment when a mobile device returns to a previous network, but these are not essential in a minimal low-cost device.


Page maintained by Stuart Cheshire