Skip to content

DHCP Relay: Forwarding Requests Across Subnets and VLANs

DHCP Relay: Forwarding Requests Across Subnets and VLANs

Section titled “DHCP Relay: Forwarding Requests Across Subnets and VLANs”

A DHCP relay agent forwards client broadcast requests to a DHCP server on a different subnet. Without relay, DHCP clients can only reach servers on the same broadcast domain. With relay, a single centralized DHCP server can serve multiple subnets or VLANs.

RouterOS implements DHCP relay in /ip dhcp-relay. Each relay instance binds to one client-facing interface and forwards requests to one or more configured server IPs.

┌─────────────┐ broadcast ┌─────────────┐ unicast ┌─────────────┐
│ Client │ ──────────────────▶ │ RouterOS │ ─────────────▶ │ DHCP │
│ 192.168.1.x │ DHCPDISCOVER │ Relay │ DHCPDISCOVER │ Server │
│ │ │ (giaddr set)│ │ 10.0.0.1 │
└─────────────┘ └─────────────┘ └─────────────┘

The relay intercepts the client’s broadcast, sets the giaddr (Gateway IP Address) field to its own local-address, then unicasts the packet to the DHCP server. The server uses giaddr to select the correct address pool and sends the reply back to the relay, which forwards it to the client.

Configure a relay instance on the interface facing DHCP clients:

/ip dhcp-relay add \
name=relay-lan \
interface=bridge-lan \
dhcp-server=10.0.0.1 \
local-address=192.168.1.1 \
disabled=no
ParameterDescription
nameIdentifying name for this relay instance
interfaceClient-facing interface that receives DHCP broadcasts
dhcp-serverIP address(es) of the remote DHCP server(s)
local-addressIP used as giaddr; set to 0.0.0.0 for auto-selection from the interface
disabledMust be no for the relay to be active
/ip dhcp-relay print detail

Expected output shows disabled=no and the correct interface/server bindings.

The dhcp-server parameter accepts a comma-separated list. The relay forwards every request to all listed servers:

/ip dhcp-relay add \
name=relay-lan \
interface=bridge-lan \
dhcp-server=10.0.0.1,10.0.0.2 \
local-address=192.168.1.1 \
disabled=no

Use this for redundant DHCP server setups. Both servers receive every request; whichever responds first wins the client.

The DHCP server must be configured to recognize relay requests. Use the relay property to match the giaddr sent by the relay:

# On the DHCP server — match relay's giaddr to serve the correct subnet
/ip dhcp-server add \
name=dhcp-subnet1 \
interface=lo \
relay=192.168.1.1 \
address-pool=pool-subnet1 \
disabled=no
/ip pool add name=pool-subnet1 ranges=192.168.1.10-192.168.1.254
/ip dhcp-server network add \
address=192.168.1.0/24 \
gateway=192.168.1.1 \
dns-server=8.8.8.8

The relay=192.168.1.1 binds this server instance to requests arriving with that giaddr. Without this, the server cannot determine which pool to assign from.

DHCP relay is interface-bound — one relay instance per client-facing interface. For multiple VLANs, create one relay entry per VLAN interface pointing to the same central server:

┌──────────────────────────────────────────────────────────┐
│ RouterOS (Relay) │
│ │
│ vlan10 (192.168.10.1) ──relay-vlan10──▶ │
│ vlan20 (192.168.20.1) ──relay-vlan20──▶ 10.0.0.1 │
│ vlan30 (192.168.30.1) ──relay-vlan30──▶ DHCP Server │
└──────────────────────────────────────────────────────────┘

Relay Configuration (on the router with VLAN interfaces)

Section titled “Relay Configuration (on the router with VLAN interfaces)”
/ip dhcp-relay
add name=relay-vlan10 interface=vlan10 dhcp-server=10.0.0.1 local-address=192.168.10.1 disabled=no
add name=relay-vlan20 interface=vlan20 dhcp-server=10.0.0.1 local-address=192.168.20.1 disabled=no
add name=relay-vlan30 interface=vlan30 dhcp-server=10.0.0.1 local-address=192.168.30.1 disabled=no

Server Configuration (on the central DHCP server)

Section titled “Server Configuration (on the central DHCP server)”
/ip pool
add name=pool-vlan10 ranges=192.168.10.10-192.168.10.254
add name=pool-vlan20 ranges=192.168.20.10-192.168.20.254
add name=pool-vlan30 ranges=192.168.30.10-192.168.30.254
/ip dhcp-server
add name=dhcp-vlan10 interface=lo relay=192.168.10.1 address-pool=pool-vlan10 disabled=no
add name=dhcp-vlan20 interface=lo relay=192.168.20.1 address-pool=pool-vlan20 disabled=no
add name=dhcp-vlan30 interface=lo relay=192.168.30.1 address-pool=pool-vlan30 disabled=no
/ip dhcp-server network
add address=192.168.10.0/24 gateway=192.168.10.1 dns-server=8.8.8.8
add address=192.168.20.0/24 gateway=192.168.20.1 dns-server=8.8.8.8
add address=192.168.30.0/24 gateway=192.168.30.1 dns-server=8.8.8.8

Each relay instance sends a distinct giaddr so the server can select the correct pool per VLAN.

DHCP uses UDP ports 67 (server) and 68 (client). If the relay router has firewall filter rules, ensure DHCP traffic is allowed through:

# Allow relay to receive DHCP from clients
/ip firewall filter add chain=input action=accept protocol=udp dst-port=67 \
comment="Allow DHCP relay input" place-before=0
# Allow relay to forward DHCP to/from server
/ip firewall filter add chain=forward action=accept protocol=udp dst-port=67,68 \
comment="Allow DHCP relay forwarding" place-before=0

NAT warning: If masquerade is active on the uplink toward the DHCP server, it will overwrite the giaddr field and break relay. Add an exception before the masquerade rule:

/ip firewall nat add chain=srcnat action=accept protocol=udp dst-port=67,68 \
comment="Exclude DHCP relay from masquerade" place-before=0
/ip dhcp-relay print detail

Confirm disabled=no and verify the interface and dhcp-server values are correct.

Use packet sniffer to confirm traffic is flowing in both directions:

# Watch for DHCP on the client-facing interface
/tool sniffer quick interface=vlan10 ip-protocol=udp port=67,68
# Watch for relayed packets on the uplink to the DHCP server
/tool sniffer quick interface=ether1 ip-protocol=udp port=67,68

If you see DHCP broadcasts arriving on the client interface but no unicast packets leaving toward the server, the relay is not forwarding — check the relay instance is enabled and that there is a route to the DHCP server.

/log print where topics~"dhcp"

DHCP relay activity and errors appear under the dhcp topic.

SymptomLikely CauseFix
Clients get no IPRelay disabledset [find] disabled=no
Relay not forwardingNo route to DHCP serverAdd route to server subnet
Server assigns wrong poolrelay= mismatch on serverMatch relay= to local-address
Server gets requests but won’t replyMasquerade overwriting giaddrAdd NAT exception for UDP 67/68
Firewall dropping packetsMissing filter accept rulesAdd input/forward accept for UDP 67/68
Clients in one VLAN get IPs from wrong poolWrong local-address on relayEnsure each relay uses its own VLAN interface IP

On the DHCP server, list active server instances and confirm each has the correct relay= address:

/ip dhcp-server print detail

Cross-reference the relay field on each server instance with the local-address on the corresponding relay entry.

  • DHCP Relay Option 82 — insert Circuit ID and Remote ID for per-location address policies and ISP wholesale scenarios
  • DHCP Server and Client — full DHCP server, client, leases, and DHCPv6 reference
  • NAT — masquerade configuration and avoiding NAT conflicts with relay