feat(ping): implement ping and a batched ping_sweep over the diagnostics API
CI / test (3.10) (push) Failing after 19s
CI / test (3.11) (push) Failing after 8s
CI / test (3.12) (push) Failing after 11s
CI / test (3.9) (push) Failing after 8s

OPNsense has no synchronous ping endpoint. /api/diagnostics/ping is a job API —
create, start, read statistics, stop, remove — so a single ping costs five
requests and roughly a second of waiting, which makes the generic per-host
sweep from napalm-device-types unusable for a whole subnet.

The override exploits what the job API does offer instead: jobs are
independent and run on the firewall in parallel, and search_jobs reports all of
them in one response. A batch (32 by default) is created and started, waited
for once, harvested with a single request and then cleaned up, so waiting time
per batch is constant rather than linear in hosts. PING_SWEEP_MAX_TARGETS
bounds the sweep as a whole — this runs on production firewalls.

Two details the API forces: results are polled, because search_jobs signals the
running ping with SIGINFO and then parses whatever it has written so far, so
the first read of a healthy host can still show zero probes; and the model's
root node is read from /get rather than hardcoded, so a rename in a future
OPNsense release cannot silently break job creation.

Tested against mocked API responses only — no live device is reachable at the
moment, so the endpoint shapes come from the OPNsense sources (PingController,
scripts/interfaces/ping.py).
This commit is contained in:
Christian Manivong
2026-08-13 16:51:05 +07:00
parent 1f29d9d57d
commit f934cc0cfa
4 changed files with 710 additions and 1 deletions
+26
View File
@@ -87,9 +87,35 @@ arguments.
| `get_bgp_neighbors` | ✅ ² | `GET /api/quagga/bgp/get` + `GET /api/quagga/diagnostics/bgpneighbors` |
| `get_vlans` | ✅ | `GET /api/interfaces/vlan_settings/search_item` |
| `get_mac_address_table` | ❌ | Not applicable (firewall, no L2 switching) |
| `ping` | ✅ | `POST /api/diagnostics/ping/set` + `start` + `search_jobs` + `stop`/`remove` |
| `ping_sweep` | ✅ ³ | same endpoints, one batch of parallel jobs at a time |
> ¹ Requires the `os-lldpd` plugin. Returns empty dict if the plugin is not installed.
> ² Requires the `os-frr` (FRR/Quagga) plugin. Returns empty dict if the plugin is not installed or FRR is not running.
> ³ Overrides the generic per-host loop from `napalm-device-types`.
### Ping
OPNsense has no synchronous ping endpoint: `/api/diagnostics/ping` is a *job*
API — create, start, read statistics, stop, remove. A single ping therefore
costs five requests and about a second of waiting, which makes the generic
sequential sweep from `napalm-device-types` unusable for a whole subnet.
`ping_sweep` exploits what the job API does offer instead: jobs are
independent and run on the firewall in parallel, and `search_jobs` reports all
of them in one response. It creates and starts a batch
(`PING_SWEEP_BATCH_SIZE`, default 32), waits once, reads every result with a
single request, then cleans the batch up — waiting time per batch is constant
rather than linear in hosts. `PING_SWEEP_MAX_TARGETS` (default 512) bounds the
sweep as a whole; both are deliberately conservative, since this runs on
production firewalls.
Results are polled rather than read once: `search_jobs` signals the running
ping with `SIGINFO` and parses whatever it has written so far, so the
statistics line lands in the log slightly after the request that triggered it.
`ttl` and `vrf` are accepted for NAPALM compatibility and ignored — the API
has no equivalent.
## Config management