Reservation lease time; reservations by MAC address or client ID

- A reservation can have its own lease time (--lease-time, the
  reservation dialog), over the subnet's. Schema migration 6.
- A reservation with a MAC address and a client ID matches either one
  (a dual-boot machine sends two client IDs from one MAC); before, it
  was found by MAC and then refused. A lease of the reserved address by
  the client's other identity counts as its own.
- The Leases page shows a client's client ID; reserving a lease uses
  both, or one with --by / the dialog's choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-18 20:26:24 +01:00
1 parent abb2ee0fd7
commit 4fd72998ec
20 files changed
+252 -65

No files matched your search

+2 -2
View File
@@ -111,7 +111,7 @@ out. `lease_time` 0 means the settings'.
| | |
|---|---|
| `GET /reservations[?subnet=REF]` | each with `subnet_id`, `subnet` and its current `lease` |
| `POST /reservations` | `{"ip", "mac", "client_id", "hostname", "options", "disabled", "comment"}`; `ip` and `mac` or `client_id` needed |
| `POST /reservations` | `{"ip", "mac", "client_id", "hostname", "options", "lease_time", "disabled", "comment"}`; `ip` and `mac` or `client_id` needed (with both, either matches); `lease_time` 0 is the subnet's |
| `GET`, `PATCH`, `DELETE /reservations/{ref}` | by ID, address, or MAC address (when it has one reservation) |
### Leases and activity
@@ -121,7 +121,7 @@ out. `lease_time` 0 means the settings'.
| `GET /leases[?subnet=&state=&interface=&q=]` | every lease, with its state now (`active`, `expired`, `released`, `declined`), `subnet` and its reservation, and `last_seen` when the client last answered a ping (left out if it never has); `q` searches address, MAC and host name |
| `GET /leases/{ip}` | one |
| `DELETE /leases/{ip}` | forget it (audited) |
| `POST /leases/{ip}/reserve` | make it a reservation; optional `{"hostname", "comment"}` |
| `POST /leases/{ip}/reserve` | make it a reservation; optional `{"hostname", "comment", "by"}`, `by` being `mac`, `client_id` or `both` (the default) |
| `GET /events[?mac=&subnet=&interface=&limit=]` | the latest DHCP messages, newest first (the last 1000 are kept in memory). `subnet` (ID, name or prefix) keeps messages for its addresses, and those without an address on its interface |
### History and import
+3 -3
View File
@@ -77,8 +77,8 @@ one. An option Steward doesn't know: `--option 224:string=hello`.
|---|---|
| `reservation list [--subnet SUBNET]` | reservations, whether each client is online, and when it last answered a ping |
| `reservation show RES` | RES is its ID, address or MAC address |
| `reservation add IP MAC [--hostname H] [--client-id HEX] [--option NAME=VALUE]... [--comment C]` | `-` for MAC with `--client-id` |
| `reservation update RES [--ip] [--mac] [--client-id] [--hostname] [--option]... [--unset-option]... [--comment]` | |
| `reservation add IP MAC [--hostname H] [--client-id HEX] [--lease-time 7d] [--option NAME=VALUE]... [--comment C]` | `-` for MAC with `--client-id`; with both, either matches |
| `reservation update RES [--ip] [--mac] [--client-id] [--hostname] [--lease-time 7d\|default] [--option]... [--unset-option]... [--comment]` | |
| `reservation enable\|disable RES` | use a reservation, or keep it but ignore it |
| `reservation delete RES` | |
@@ -88,7 +88,7 @@ one. An option Steward doesn't know: `--option 224:string=hello`.
|---|---|
| `lease list [--subnet S] [--state STATE] [--interface I] [--search TEXT] [-a]` | active and held-back leases; `-a` all |
| `lease show IP` | one lease |
| `lease reserve IP [--hostname H]` | make the address its client's reservation |
| `lease reserve IP [--hostname H] [--by mac\|client-id\|both]` | make the address its client's reservation, by its MAC address and client ID (either matches) unless `--by` says one |
| `lease delete IP [-y]` | free the address at once |
### activity
+12 -5
View File
@@ -58,15 +58,20 @@ steward reservation add 10.0.10.20 aa:bb:cc:dd:ee:01 --hostname nas
steward lease reserve 10.0.10.57 # the address a client has now
```
* **The client** is known by its MAC address, or by its client identifier
(option 61) when the reservation has one (`--client-id`; give `-` as the
MAC). Some devices change their identifier but not their MAC address,
and others the other way round. When unsure, use the MAC address.
* **The client** is known by its MAC address, its client identifier
(option 61, `--client-id`; give `-` as the MAC for an identifier alone),
or both. With both, **either one** gets the client its address: a
machine that boots two systems sends different identifiers from one MAC
address, and a device with a randomised MAC may keep its identifier.
The Leases page and `steward lease show` show the identifier a client
sent; `steward lease reserve IP` uses both when it sent one (`--by mac`
or `--by client-id` for just one).
* **The address picks the subnet**: the subnet whose network holds it. It
may be inside a pool or outside one; either way, nobody else gets it.
* **The host name** is sent to the client (option 12).
* **Options** set on the reservation are for that client only, and win
over the subnet's and the settings'.
* **A lease time** of its own (`--lease-time 7d`) wins over the subnet's.
* **A device on two VLANs** can have a reservation in each subnet. Within
one subnet, a client has at most one.
@@ -108,7 +113,9 @@ a list, it gets every option set for it.
## Lease times
The settings have the default (12 hours, `steward settings set
--lease-time 1d`); a subnet can have its own (`--lease-time 1h`). Clients
--lease-time 1d`); a subnet can have its own (`--lease-time 1h`), and a
reservation its own over that (`steward reservation update nas
--lease-time 7d`). Clients
renew halfway through. Short times let changes reach clients sooner;
long ones keep clients working longer if Steward is down.