Wheelhouse docs

DHCP relay#

The second tab of DHCP, at /dhcp. It owns service dhcp-relay.

A DHCP client broadcasts, and a broadcast does not cross a router. When the server that should answer lives on another segment — a central server for the whole site, rather than one per router — the router in between has to pick the request up and forward it. That is a relay, and this tab is its whole configuration.

Where the data comes from#

GET /api/config?path=service dhcp-relay. A read of an unset path is caught and treated as "not configured" rather than as an error, so a router without a relay shows the empty state and not a failure. The interface pickers come from GET /api/interfaces/detail with lo removed — ui/src/pages/DhcpExtras.tsx.

When it is configured#

The left panel reads out four values:

FieldRead from
Listens onlisten-interface, plus any legacy interface values
Forwards viaupstream-interface
Serversserver
Statedisabled when disable is present, otherwise enabled

Remove relay stages one operation:

delete service dhcp-relay

When it is not#

The empty state names the concept and gives the three commands, and — for a principal that may write — an editor appears beside it. Once a relay exists the editor disappears: this tab creates or deletes, it does not edit. Adding a second server or a third listen interface to an existing relay is a CLI command or a config-tree edit.

The editor#

ControlCommandRequired
Listen on — a checkbox per interfaceset service dhcp-relay listen-interface <if> per ticked interfaceat least one
Forward out of — a menuset service dhcp-relay upstream-interface <if>yes
DHCP servers — comma separatedset service dhcp-relay server <addr> per addressat least one

Nothing is staged until all three are satisfied. A complete result:

set service dhcp-relay listen-interface eth0
set service dhcp-relay upstream-interface eth1
set service dhcp-relay server 10.0.3.5

The server list is split on any run of whitespace or commas, so 10.0.3.5, 10.0.3.6 produces two server lines.

Which interfaces go where#

  • Listen on is the segment with the clients: the LAN, the VLAN, the guest network. Tick every segment whose clients should reach the remote server.
  • Forward out of is the interface facing the server. It is what the relay uses as the source address of the forwarded request, and it is that address the server uses to pick a pool. Get it wrong and the server answers from the wrong subnet — or does not answer at all, because no pool matches.

Both pickers are built from the interface list that GET /api/interfaces/detail produces, which does not enumerate VLAN sub-interfaces. Relaying on a VLAN is a CLI command.

What has to be true elsewhere#

A relay is three-sided, and this page only configures one of them.

  1. The router must be able to reach the server. A route to the server's subnet, and a firewall that allows the forwarded traffic out and the reply back in.
  2. The server must have a pool for the relayed subnet. It picks the pool from the relay's source address. A server with only its own local subnet configured will silently ignore requests from yours.
  3. The clients must have nothing else answering. See the warning above.

What breaks if you get it wrong#

  • Both a relay and a server on one interface. Inconsistent addressing, described above.
  • The wrong upstream interface. The server sees the request as coming from a subnet it does not serve, and does not answer. The clients time out, which looks exactly like the relay not being configured at all.
  • The relay's own segment address missing. The relay needs an address on the listen interface to be a plausible source. An interface with no address relays nothing.
  • Firewall. The router now originates traffic to the server and receives replies. A default-drop input policy that was written when the router answered DHCP locally does not necessarily allow this.

See also#

  • DHCP — the local server, which is the alternative to relaying.
  • DHCP and IPv6 — the third tab.
  • Interfaces — the interfaces the pickers list, and why a VLAN is not among them.
  • Static routes — reaching the server's subnet.

Checked against ui/src/pages/DhcpExtras.tsx (RelayTab), ui/src/pages/Dhcp.tsx, agent/opmode.go (collectInterfaces), ui/src/lib/api.ts.

Updated 2026-09-02 manual network dhcp relay