QoS#
Network → QoS shows what the configuration asks for and what the kernel is really
doing, side by side, and offers one editor: a CAKE policy attached as egress on one
interface. It writes four kinds of line into the qos subtree and nothing else. If the
config asks for CAKE and the kernel reports fq_codel, the page says so in amber
instead of drawing a green badge over the disagreement.
The header carries a Policies / CLI toggle and a + CAKE policy button. The CLI
view is GET /api/config/commands?path=qos — the whole shaping configuration as set
commands, which is the copy you paste into a ticket.
Where the two halves come from#
| Half | Endpoint | Router command behind it |
|---|---|---|
| What is configured | GET /api/qos | retrieve of the qos subtree |
| What is installed | GET /api/qos/stats, polled every 4 s | show interfaces <kind> <name> per shaped interface |
handleQosStats is worth understanding, because it is the reason the page is honest
about non-ethernet interfaces. For each interface named under qos interface it first
tries show interfaces ethernet <name>; when that fails it looks the interface's real
kind up in the configuration and asks again. A shaped bond, bridge, VLAN or WireGuard
tunnel is not an ethernet node, and asking for the wrong one reported "no qdisc" for a
shaper that was running — handleQosStats in agent/main.go,
with the kind lookup in agent/opmode.go.
From the parsed detail it takes three things: the qdisc name, and the transmit and receive counters.
The attachment panels#
One panel per interface named under qos interface:
| Row | Meaning |
|---|---|
| Egress policy | The policy name attached to the outbound direction. |
| Ingress policy | The policy name attached inbound, if any. |
| Kernel qdisc | What the kernel reports on that interface right now, or unknown. |
| TX bytes / TX dropped / RX bytes | Counters from the same read. |
The title carries a badge with the kernel's qdisc. When the configured policy's kind and the kernel's qdisc disagree, that badge turns amber and a drift badge appears beside it naming both: "config asks for cake, kernel reports fq_codel". Drift here almost always means the commit that attached the policy did not take, or something outside the configuration re-attached a qdisc.
Below the attachments, one panel per policy kind (cake, shaper, fq-codel, whatever
the tree holds), listing each policy by name with every field it declares. Those panels
render whatever is in the configuration — they are not limited to what the editor can
write.
The editor#
+ CAKE policy opens a side panel; Edit on an attachment opens the same panel pre-filled from that interface's existing egress policy. Four inputs:
| Field | Default in the form | What it writes |
|---|---|---|
| Policy name | WAN-OUT (hidden when editing an existing attachment) | the policy's node name |
| Interface | eth1 (hidden when editing an attachment) | which interface the policy attaches to |
| Bandwidth | 70mbit | bandwidth <value> |
| Flow isolation | dual-src-host | flow-isolation <value> |
| RTT (ms) | 100 | rtt <value> |
Flow isolation is a fixed list: flow, dual-src-host, dual-dst-host, src-host,
dst-host, host, triple-isolate.
The panel shows the exact commands before you stage them, and staging them puts them in the Commit Bar like any other change. For the defaults above:
set qos policy cake WAN-OUT bandwidth 70mbit
set qos policy cake WAN-OUT flow-isolation dual-src-host
set qos policy cake WAN-OUT rtt 100
set qos interface eth1 egress WAN-OUTDetach — offered only when you opened the panel from an existing attachment — stages a single operation:
delete qos interface eth1That removes the attachment and leaves the policy definition in the tree, so you can
re-attach it without retyping it. To remove the policy itself, delete
qos policy cake <name> from the Config tree page or the CLI.
The empty state#
A router with nothing under qos shows one panel with three commands, which are the
whole minimum configuration:
set qos policy cake WAN-OUT bandwidth 70mbit
set qos policy cake WAN-OUT flow-isolation dual-src-host
set qos interface eth1 egress WAN-OUTWhat the editor does not write#
This matters more than the list of what it does, because the product's own plan asks for more than has shipped.
Also absent: per-class or per-host bandwidth limits from this page, a priority-queue editor, and any measurement of the link the shaper is on. The page never tests your line rate; the number in the form is the number you typed.
Integration offers on this page#
If an installed app declares a hint for the qos page it appears here as a card under
the header. The catalogue ships one: Speedtest Tracker offers "Set the shaper from
measured throughput", which is advice, not commands — it carries no operations, so
there is no Stage this change button on it. How hints work is on
Apps — integration offers.
Checking it from the CLI#
The two reads the page makes, by hand:
show configuration commands | match qos
show interfaces ethernet eth1The second one's qdisc field is what the Kernel qdisc row shows.
See also#
- Dashboard — the qdisc badge on each interface panel comes from the same read.
- Interfaces — the interface a policy attaches to.
- Uplinks (multi-WAN) — which interface is carrying traffic, and therefore which one is worth shaping.
- Telemetry — why a 4-second poll is cheaper than it looks.
- Apps — integration offers — the hint card above the panels.
Checked against ui/src/pages/Qos.tsx,
agent/main.go,
agent/opmode.go,
ui/src/lib/format.ts,
agent/catalog.json, PLAN.md.