Skip to main content
  1. Network Articles/
  2. IPv4 Articles/

DHCP Relay Agent

Table of Contents

What Is a DHCP Relay Agent

A DHCP DISCOVER is sent with a destination IP address of 255.255.255.255 and a broadcast destination MAC address. Routers do not forward broadcasts, so when the client and the DHCP server are on different segments, the DISCOVER never reaches the server on its own.

Putting a DHCP server on every segment would solve it, but that means one server per site or per VLAN, which is not practical. Instead, the router attached to the client’s segment receives the broadcast on the client’s behalf, converts it into a unicast, and forwards it to a DHCP server on another segment. That function is called a DHCP relay agent.

The behavior of a relay agent is specified in RFC 2131, and the detailed requirements it inherits as a BOOTP relay are defined in RFC 1542. Just as DHCP inherited the BOOTP message format, the relay mechanism was inherited from the BOOTP relay agent.

A relay agent is a layer 3 function, and it is not the same as “broadcast forwarding,” which floods a broadcast onto another segment as it is. A relay agent rebuilds the DHCP message it received as a new unicast IP packet before sending it to the server, so no broadcast leaks onto the path in between.

The Role of giaddr

The key to understanding a relay agent is the giaddr (Gateway IP Address) field of the DHCP message.

FieldAs sent by the clientAfter passing through the relay agent
giaddr0.0.0.0The relay agent writes in the IP address of its client-side interface
hops0Incremented by one for every relay agent the message passes through
Destination IP address255.255.255.255The DHCP server’s IP address (unicast)
Source IP address0.0.0.0The relay agent’s IP address

giaddr is not merely a record of where the message has been: it is the information the server uses to decide which pool to allocate from. The server looks at the giaddr of the message it receives and picks the pool for the subnet that contains that address. If the relay agent’s client-side interface is 192.168.20.1/24, that value goes into giaddr, so the server allocates from the 192.168.20.0/24 pool.

The server’s replies (OFFER and ACK) are also returned as unicast to giaddr. The relay agent receives them and forwards them to the client. The server never needs to know where the client is; it only has to answer based on giaddr.

hops counts how many relays a message has passed through and exists to prevent loops. RFC 1542 recommends that a relay agent discard a message whose hops exceeds 4. Ordinary designs never chain several relays, so this value is almost always still 1.

The Packet Flow Through a Relay

Here is the flow of a DORA in a setup with a client on 192.168.20.0/24, relay agent R1, and a DHCP server at 10.1.2.2.

sequenceDiagram
    participant C as Client
192.168.20.0/24 participant R as R1 (relay)
Gi1: 192.168.20.1
Gi2: 10.1.2.1 participant S as DHCP server
10.1.2.2 C->>R: 1. DISCOVER (broadcast)
Destination: 255.255.255.255
giaddr = 0.0.0.0, hops = 0 Note over R: Writes 192.168.20.1 into giaddr,
increments hops to 1,
converts to unicast R->>S: 2. DISCOVER (unicast)
10.1.2.1 to 10.1.2.2
giaddr = 192.168.20.1, hops = 1 Note over S: giaddr is 192.168.20.1,
so the 192.168.20.0/24 pool is chosen S->>R: 3. OFFER (unicast)
Destination: giaddr = 192.168.20.1
yiaddr = 192.168.20.101 R->>C: 4. OFFER (broadcast)
Forwarded onto the client segment Note over C,S: REQUEST and ACK follow the same path
  1. The client sends its DISCOVER as a broadcast in the usual way. It is unaware that a relay agent exists.
  2. R1 receives it on GigabitEthernet1, writes the receiving interface’s IP address (192.168.20.1) into giaddr, increments hops to 1, and forwards it as a unicast to the server named by ip helper-address.
  3. The server works out which segment the request came from using giaddr, picks an address from the matching pool, and returns the OFFER as a unicast to giaddr.
  4. R1 receives the OFFER and forwards it onto the client segment. Because the client does not have an address yet, it is normally forwarded as a broadcast.

REQUEST and ACK follow the same path. Neither the client nor the server treats the relay as a special case; the whole mechanism rests on the single giaddr field.

During a lease renewal (RENEWING, when T1 expires), the client already knows the server’s IP address from Option 54, so it sends the REQUEST directly to the server as a unicast. That is not a broadcast, so it reaches the server by ordinary routing and does not go through the relay agent. The relay is involved for the broadcast cases: a new acquisition and REBINDING.

Configuration with ip helper-address

On Cisco IOS / IOS XE, a relay agent is enabled by configuring ip helper-address on the client-side interface. Note that it is not the server-side interface.

Relay agent configuration example
interface GigabitEthernet1
 description to client segment
 ip address 192.168.20.1 255.255.255.0
 ip helper-address 10.1.2.2

Where several DHCP servers exist, writing multiple ip helper-address lines forwards the message to all of them.

The server needs a route back to the client’s segment. OFFERs and ACKs are returned to giaddr (192.168.20.1), so the relay cannot work unless the server can reach that address.

ip helper-address forwards UDP broadcasts other than DHCP as well. Cisco IOS forwards the following eight services by default.

PortService
37TIME
49TACACS
53DNS
67BOOTP / DHCP server
68BOOTP / DHCP client
69TFTP
137NetBIOS Name Service
138NetBIOS Datagram Service

To forward only DHCP, disable the ones you do not want individually with no ip forward-protocol udp <port>. Unintentionally forwarding DNS or NetBIOS broadcasts to another segment leads to needless traffic and to security problems.

Option 82 (Relay Agent Information)

Option 82 is information a relay agent attaches to a DHCP message, defined in RFC 3046. It tells the server “which port (circuit) of which relay agent this request came from,” and it carries sub-options inside.

Sub-optionNameContents
1Circuit IDAn identifier for the circuit the request arrived on, such as a physical port number or a VLAN ID
2Remote IDAn identifier for the relay agent itself, such as a MAC address or a host name

The relay agent inserts Option 82 when it forwards a message from the client, and strips Option 82 out before forwarding the server’s reply to the client. The client therefore never sees Option 82.

On the server side this information is used for policies such as “assign this particular address only to equipment attached to this port,” and for auditing which addresses were handed out. Combined with DHCP Snooping on a switch, it also lets the binding table carry port information.

The configuration on Cisco IOS / IOS XE is as follows.

Configuring Option 82
(on the relay agent)
ip dhcp relay information option

(on the DHCP server, to also accept Option 82 packets whose giaddr is 0)
ip dhcp relay information trust-all
By default a DHCP server treats a message that carries Option 82 while giaddr is still 0.0.0.0 as invalid and discards it, because Option 82 being present without having gone through a relay agent suggests spoofing. In designs where a switch running DHCP Snooping inserts only Option 82 without rewriting giaddr, the server needs ip dhcp relay information trust-all.

Verification on Real Devices

R3 (client), R1 (relay agent), and R2 (DHCP server) were connected on separate segments, and address acquisition through the relay was verified on real devices. All three routers run Cisco IOS XE 17.03.08a (csr1000v).

Taking a capture at two points at once is the key to this verification: it lets the same message be compared before and after the relay.

R2 (the server) is configured with the following pool and return route. Without the return route the OFFER cannot be sent back to giaddr, and the relay does not work.

R2 (DHCP server) configuration
ip dhcp excluded-address 192.168.20.1 192.168.20.100
!
ip dhcp pool LAN20
 network 192.168.20.0 255.255.255.0
 default-router 192.168.20.1
 dns-server 10.1.2.2
 domain-name kazulog.example
 lease 0 0 2
!
ip route 192.168.20.0 255.255.255.0 10.1.2.1

R1 (the relay) has ip helper-address on its client-side GigabitEthernet1.

R1 (relay agent) configuration
interface GigabitEthernet1
 description to R3 Gi1 (client segment / capture A)
 ip address 192.168.20.1 255.255.255.0
 ip helper-address 10.1.2.2

Test Sequence and the Server-Side Counters

STEPOperationR3’s Gi1DISCOVER rcvdOFFER sentREQUEST rcvdACK sent
0Initial state (R3’s Gi1 shut down)unassigned0000
1no shutdown on R3’s Gi1192.168.20.1021111
2Wait for T1 (60 seconds) to expire twice192.168.20.1021133
3Remove ip helper-address from R1, then release/renewunassigned1133
4Restore ip helper-address and renew192.168.20.1032255
5Enable Option 82, then release/renew192.168.20.1043377

Look at STEP 3. The client cannot obtain an address and stays unassigned, and the server’s DISCOVER counter does not move from 1. Removing ip helper-address stopped the DISCOVER from reaching the server, and the numbers show it.

How the Same DISCOVER Changes Across the Relay

Here is the DORA from STEP 1 as seen in the two captures. First, the client side.

Capture A (between R3 and R1): the DORA seen on the client side
    1   0.000000      0.0.0.0 → 255.255.255.255 DHCP 357 DHCP Discover - Transaction ID 0x26d1
    2   0.021989 52:54:00:86:de:30 → Broadcast    ARP 60 Who has 192.168.20.102? Tell 192.168.20.1
    3   2.051454 192.168.20.1 → 255.255.255.255 DHCP 372 DHCP Offer    - Transaction ID 0x26d1
    4   2.057779      0.0.0.0 → 255.255.255.255 DHCP 375 DHCP Request  - Transaction ID 0x26d1
    5   2.070234 192.168.20.1 → 255.255.255.255 DHCP 372 DHCP ACK      - Transaction ID 0x26d1
Download just these No.1 to No.5 (the DORA on the client side)

Now the server side. It is the same exchange, with the same Transaction ID 0x26d1, but everything is unicast.

Capture B (between R1 and R2): the same DORA seen on the server side
    1   0.000000 192.168.20.1 → 10.1.2.2     DHCP 357 DHCP Discover - Transaction ID 0x26d1
    2   2.038251     10.1.2.2 → 192.168.20.1 DHCP 372 DHCP Offer    - Transaction ID 0x26d1
    3   2.053646 192.168.20.1 → 10.1.2.2     DHCP 375 DHCP Request  - Transaction ID 0x26d1
    4   2.060189     10.1.2.2 → 192.168.20.1 DHCP 372 DHCP ACK      - Transaction ID 0x26d1
Download just these No.1 to No.4 (the DORA on the server side)

Comparing the contents of the DISCOVER makes the fields the relay agent rewrote obvious. The first block is the client side, the second the server side.

Capture A No.1: the DISCOVER as the client sent it
    Source Address: 0.0.0.0
    Destination Address: 255.255.255.255
Dynamic Host Configuration Protocol (Discover)
    Message type: Boot Request (1)
    Hops: 0
    Transaction ID: 0x000026d1
    Bootp flags: 0x8000, Broadcast flag (Broadcast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 0.0.0.0
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: 52:54:00:49:49:5a (52:54:00:49:49:5a)
Capture B No.1: the same DISCOVER as the relay forwarded it
    Source Address: 192.168.20.1
    Destination Address: 10.1.2.2
Dynamic Host Configuration Protocol (Discover)
    Message type: Boot Request (1)
    Hops: 1
    Transaction ID: 0x000026d1
    Bootp flags: 0x8000, Broadcast flag (Broadcast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 0.0.0.0
    Next server IP address: 0.0.0.0
    Relay agent IP address: 192.168.20.1
    Client MAC address: 52:54:00:49:49:5a (52:54:00:49:49:5a)
FieldClient sideServer side
Source IP address0.0.0.0192.168.20.1 (the relay’s address)
Destination IP address255.255.255.25510.1.2.2 (the server’s address)
Hops01
Relay agent IP address (giaddr)0.0.0.0192.168.20.1
Transaction ID0x000026d10x000026d1 (the same)
Client MAC address52:54:00:49:49:5a52:54:00:49:49:5a (the same)

As described earlier, the relay agent rebuilds the IP packet while carrying the DHCP message through unchanged apart from giaddr and hops. Because Transaction ID and Client MAC address stay the same, the server can identify the client correctly and the replies can be matched back to it.

From the client’s point of view, the source of the OFFER and the ACK is 192.168.20.1, the relay agent. To the client the relay looks like the DHCP server, while the Option 54 (Server Identifier) the client received holds the real server’s address.

R3 show dhcp lease
R3#show dhcp lease
Temp IP addr: 192.168.20.102  for peer on Interface: GigabitEthernet1
Temp  sub net mask: 255.255.255.0
   DHCP Lease server: 10.1.2.2, state: 5 Bound
   DHCP transaction id: 26D1
   Lease: 120 secs,  Renewal: 60 secs,  Rebind: 105 secs
Temp default-gateway addr: 192.168.20.1
   Next timer fires after: 00:00:17
   Retry count: 0   Client-ID: cisco-5254.0049.495a-Gi1
   Hostname: R3

DHCP Lease server is 10.1.2.2, off the client’s own segment, while default-gateway is the relay’s 192.168.20.1 — the two point at different places, which is characteristic of a relayed setup.

The Lease Renewal Does Not Go Through the Relay

This is the renewal that happened when T1 (60 seconds) expired. It is No.10 and No.11 of the attached client-side capture.

Capture A No.10 and No.11: the lease renewal at T1 expiry
   10  66.279226 192.168.20.102 → 10.1.2.2     DHCP 363 DHCP Request  - Transaction ID 0x26d1
   11  66.285223     10.1.2.2 → 192.168.20.102 DHCP 372 DHCP ACK      - Transaction ID 0x26d1
Download just these No.10 and No.11 (the lease renewal)

The source is the client’s own 192.168.20.102 and the destination is the server’s 10.1.2.2; the relay agent’s address does not appear. Both packets still carry giaddr of 0.0.0.0 and hops of 0. As described earlier, a renewal is a unicast to the server rather than a broadcast, so it does not go through the relay processing and simply passes through R1 by ordinary routing.

The same packets also appear in the server-side capture. R1 is not relaying them; it is merely forwarding them as a router.

What Happens When ip helper-address Is Removed

In STEP 3, ip helper-address was removed from R1’s GigabitEthernet1 and R3 was made to acquire an address again.

Capture A No.16 to No.18: DISCOVERs that get no answer
   16 179.110077      0.0.0.0 → 255.255.255.255 DHCP 357 DHCP Discover - Transaction ID 0x1439
   17 182.335039      0.0.0.0 → 255.255.255.255 DHCP 357 DHCP Discover - Transaction ID 0x1439
   18 186.335474      0.0.0.0 → 255.255.255.255 DHCP 357 DHCP Discover - Transaction ID 0x1439
Download just these No.16 to No.18 (the unanswered DISCOVERs)

The client retransmits three times with the same xid and then repeats with a new one. The client-side capture records nine of these DISCOVERs, while the server-side capture contains none at all.

CaptureSTEP 3 DISCOVERs (xid 0x1439 / 0x143a / 0x143b)
A (client side)9 packets
B (server side)0 packets

On R1 at this point, the show ip helper-address list is empty.

R1 show ip helper-address (STEP 3)
R1#show ip helper-address
Interface                  Helper-Address  VPN VRG Name             VRG State

The link stays up yet no address is obtained, and the server-side counters do not move. Those three observations together show that the broadcast is not crossing the router. Restoring ip helper-address in STEP 4 brought the DISCOVER counter from 1 to 2 and the client recovered.

Option 82 in Practice

In STEP 5, ip dhcp relay information option was configured on R1 and ip dhcp relay information trust-all on R2, and the address was acquired again. The packets are larger in the server-side capture.

Capture B No.21 to No.24: the DORA carrying Option 82
   21 387.544996 192.168.20.1 → 10.1.2.2     DHCP 373 DHCP Discover - Transaction ID 0xfb5
   22 389.551056     10.1.2.2 → 192.168.20.1 DHCP 388 DHCP Offer    - Transaction ID 0xfb5
   23 389.561390 192.168.20.1 → 10.1.2.2     DHCP 391 DHCP Request  - Transaction ID 0xfb5
   24 389.567012     10.1.2.2 → 192.168.20.1 DHCP 388 DHCP ACK      - Transaction ID 0xfb5
Download just these No.21 to No.24 (the DORA carrying Option 82)

The DISCOVER is 373 bytes, 16 bytes larger than the 357-byte DISCOVER from STEP 1 that had no Option 82. Its contents are as follows.

Option 82 in capture B No.21
    Option: (82) Agent Information Option
        Length: 14
        Option 82 Suboption: (2) Agent Remote ID
            Length: 12
            Agent Remote ID: 020a0000c0a8140100000000
    Option: (255) End
Only the Remote ID (sub-option 2) was inserted in this setup; there was no Circuit ID (sub-option 1). Within the Remote ID value 020a0000c0a8140100000000, c0a81401 is the relay agent’s interface address 192.168.20.1. What goes into Option 82 depends on the implementation and the design: where ports are distinguished, as with DHCP Snooping on a switch, a Circuit ID is inserted as well. In a router-to-router relay there is no “circuit” to distinguish, which is presumably why only the Remote ID appeared.

Looking at the same exchange in the client-side capture, on the other hand, Option 82 does not appear at all.

Capture A No.42 to No.46: the same DORA seen on the client side
   42 387.547323      0.0.0.0 → 255.255.255.255 DHCP 357 DHCP Discover - Transaction ID 0xfb5
   43 387.559201 52:54:00:86:de:30 → Broadcast    ARP 60 Who has 192.168.20.104? Tell 192.168.20.1
   44 389.562682 192.168.20.1 → 255.255.255.255 DHCP 372 DHCP Offer    - Transaction ID 0xfb5
   45 389.566898      0.0.0.0 → 255.255.255.255 DHCP 375 DHCP Request  - Transaction ID 0xfb5
   46 389.577910 192.168.20.1 → 255.255.255.255 DHCP 372 DHCP ACK      - Transaction ID 0xfb5
Download just these No.42 to No.46 (the same DORA seen on the client side)

The DISCOVER is still 357 bytes and the OFFER and ACK are still 372 bytes. Because the relay agent strips Option 82 out before forwarding to the client, the client never sees it. The behavior described earlier is observable directly as a difference in packet size.

Download the full capture A (client side)

Download the full capture B (server side)

Verification Config and show Output

At each step the following three kinds of output were collected from R1, R2, and R3, kept in separate files per router. The verification config is the ..._run.txt file (the final state is the one from STEP 5).

FileContents
..._show.txtshow version / show interfaces description / show ip interface brief / show ip route / show arp / show ip helper-address / show ip dhcp pool / show ip dhcp binding / show ip dhcp server statistics / show ip dhcp conflict / show ip dhcp relay information trusted-sources / show dhcp lease
..._log.txtshow logging narrowed to that step alone. A marker is written with send log at the start of each step, and that string is passed to show logging | begin when collecting
..._run.txtshow running-config at that step (that is, the verification config for the step)

STEP 0: initial state (R3’s Gi1 shut down)

Nodeshow outputsyslogrunning-config
R1 (relay)showlogrun
R2 (server)showlogrun
R3 (client)showlogrun

STEP 1: R3’s Gi1 brought up and an address obtained through the relay

Nodeshow outputsyslogrunning-config
R1 (relay)showlogrun
R2 (server)showlogrun
R3 (client)showlogrun

STEP 2: the lease renewed twice by the expiry of T1

Nodeshow outputsyslogrunning-config
R1 (relay)showlogrun
R2 (server)showlogrun
R3 (client)showlogrun

STEP 3: ip helper-address removed from R1, leaving the client unable to obtain an address

Nodeshow outputsyslogrunning-config
R1 (relay)showlogrun
R2 (server)showlogrun
R3 (client)showlogrun

STEP 4: ip helper-address restored and the client recovered

Nodeshow outputsyslogrunning-config
R1 (relay)showlogrun
R2 (server)showlogrun
R3 (client)showlogrun

STEP 5: Option 82 enabled (final state)

Nodeshow outputsyslogrunning-config
R1 (relay)showlogrun
R2 (server)showlogrun
R3 (client)showlogrun

References

RFCTitleSummary
RFC 2131Dynamic Host Configuration ProtocolDefines the handling of giaddr and hops and the basic behavior of a relay agent.
RFC 1542Clarifications and Extensions for the Bootstrap ProtocolThe detailed requirements for a BOOTP relay agent, including the limit on hops.
RFC 3046DHCP Relay Agent Information OptionDefines Option 82 and its sub-options (Circuit ID / Remote ID).

Related Articles