Skip to content

Hierarchical QoS

QoS is built from three objects in the qos view. A queue profile is the scheduler discipline only and carries no rate; a subscriber profile owns the rate plus an optional local priority and points at a queue profile; an assignment binds a prefix to a subscriber profile. All four collections are index-addressable lists.

Resolution order

A subscriber's effective QoS resolves in three steps: a matching assignment by longest prefix, giving its subscriber profile's rate, priority and queue profile; else the RADIUS rate on the per-service default queue profile, PPPoE or IPoE; else the service default at the port rate. show qos bindings reports the resolved result per subscriber together with its source — RADIUS, static or default — which is the first thing to check when a customer reports the wrong speed.

Queue profiles

The discipline and its tuning, with no rate attached. Four disciplines are available. delete is refused while a subscriber profile or service default still references the profile. Queueing changes take effect on commit rather than needing a restart: commit stages the model and activates it by building a new scheduler generation from the committed config, and save persists it.

cli
qos queue-profile add    <name> <tb|pfifo|fq_codel|cake> [tuning...]
qos queue-profile modify <N> <name> <disc> [tuning...]
qos queue-profile insert <N> <name> <disc> [tuning...]
qos queue-profile delete <N>
qos queue-profile move   <N> <M>

qos queue-profile modify 3 fq fq_codel qsize 4096 flows 1024 \
    target 5ms interval 100ms ecn on

qos queue-profile add cake0 cake qsize 4096 target 5ms interval 100ms \
    overhead 18 rtt 100 diffserv diffserv4 \
    flow-mode triple-isolate ack-filter on wash on

commit ; save

Tuning keys by discipline

Only the keys valid for a discipline are accepted. The shaper is a token bucket with optional WRED or PIE AQM, so some Linux tc-style knobs are advisory: they are stored, shown in show qos marked advisory, and round-tripped, but not enforced by the data plane. The AQM knobs — target, interval, rtt and ecn — run only when AQM is enabled in the build and aqm enable is set; otherwise the discipline is tail-drop and those knobs are inert. Keep qsize generous: too small a value starves a single TCP flow below its rate.

text
ALL          qsize        packets, power of two   enforced

tb           burst        bytes (k/M)             enforced
             limit        <ms>ms                  enforced

fq_codel     flows        count                   advisory
  and cake   target       <us> / <ms>ms           enforced (AQM)
             interval     <us> / <ms>ms           enforced (AQM)
             ecn          on|off                  enforced (AQM)
             quantum      bytes                   advisory
             memory       bytes                   advisory
             ce-threshold <us>                    advisory

cake         overhead     bytes                   enforced
             rtt          <ms>                    enforced
             diffserv     besteffort|diffserv3|
                          diffserv4|diffserv8     enforced
             flow-mode    triple-isolate|flows|
                          hosts|src-host|dst-host|
                          dual-src-host|
                          dual-dst-host           advisory
             ack-filter   on|off                  advisory
             wash         on|off                  advisory
             nat          on|off                  advisory
             autorate     on|off                  advisory

Live changes without a restart

A queue profile's discipline, qsize and AQM layout are fixed when a port is built, so the daemon keeps parallel scheduler generations. Committing a queue-profile change builds a new generation from the committed config alongside the running one — live, with no restart and no separate step (the earlier qos retune command has been removed; commit does the work, and it applies the in-memory candidate rather than re-reading the config file). New sessions bind to the new generation immediately; existing sessions keep forwarding on the old generation and migrate gradually, on reauth or reconnect and through a controlled background rebind of roughly 64 subscribers every 20 milliseconds. The old generation is freed once nothing references it — show qos generations shows it drain to zero and then read free. Only one rebuild is in flight at a time; if a committed change cannot get a free generation slot because the predecessor is still draining, the profile re-point applies but the qsize and AQM rebuild is deferred until the draining generation retires. Scope is tuning existing profiles in place: adding, removing or reordering profiles, and changing the port rate or max-pipes, still need a restart.

cli
commit ; save
show qos generations      # current generation + riders per generation

Subscriber profiles

The rate lives here. Rates accept k, M and G suffixes, and rate <tx>/<rx> is also accepted. queue-profile must name an existing profile; omitted, or given as a dash, it inherits the per-service default. priority is a local priority from 1 to 8 — 1 served first under congestion, 8 last — applied when this profile backs a static assignment. It is the configured equivalent of the RADIUS Netvyn-Priority attribute, and a static assignment with its priority resolves first, overriding any RADIUS rate or priority.

cli
qos subscriber-profile add <name> rate-down <r> rate-up <r> \
    [queue-profile <qp>] [priority <1-8>]
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r> \
    [queue-profile <qp>] [priority <1-8>]
qos subscriber-profile delete <N>
qos subscriber-profile move <N> <M>

qos subscriber-profile add res-100 rate-down 100M rate-up 100M \
    queue-profile res-fq
commit

Assignments

An assignment binds a prefix to a subscriber profile. The prefix may be IPv4 or IPv6 — a host, which becomes a /32 or /128, or a prefix. Resolution is v4-first: a dual-stack subscriber matches through its framed IPv4, and the v6 assignments are consulted only when no v4 assignment matched. A v6 assignment matches either the subscriber's framed v6 or its delegated prefix. Both families share the subscriber's single shaper pipe per direction, so the plan rate is the combined v4 and v6 throughput rather than one each.

cli
qos assign add <cidr> subscriber-profile <name>
qos assign insert <N> <cidr> subscriber-profile <name>
qos assign delete <N>
qos assign move <N> <M>

qos assign add 100.64.10.0/24 subscriber-profile res-100
qos assign add 2001:db8:100::/40 subscriber-profile res-100
commit ; save

Service default queue type

Which queue profile PPPoE and IPoE subscribers run on by default. These stage into the candidate and commit applies live: the service default switches and every installed subscriber whose resolved queue profile changed is re-queued on the spot at its current rate, with RADIUS rates untouched. Subscribers pinned to a queue profile through an assignment keep that pin, because an assignment outranks the service default.

cli
qos service ppp  <queue-profile>
qos service ipoe <queue-profile>
commit

Referential integrity

References resolve against the running configuration, so a referenced object must be committed first. A subscriber profile's queue profile must already exist; an assignment's subscriber profile must already exist; and a subscriber profile still referenced by an assignment cannot be deleted. To add a new subscriber profile and an assignment that references it, commit the subscriber profile first, then the assignment.

Overhead compensation

A shaper counts the full L1 and L2 frame including PPPoE, but a speed test measures TCP payload — so a 300M pipe reads around 268M. Overhead compensation shapes each pipe a set percentage above its plan so goodput matches the plan. Roughly 8 to 12 per cent, nearer 12 for PPPoE and nearer 8 for IPoE, with 0 meaning exact plan. It stages into the candidate and commit applies it live — the global is set and every installed subscriber's pipes are rebound at their current rate so the new margin takes effect at once — while save persists it. show qos reports the active value.

cli
qos overhead-compensation <pct>
commit ; save
show qos

Checking the result

Three commands answer the three questions: what is configured, what a given subscriber actually resolved to, and whether a committed queue-profile change has finished draining onto the new generation.

cli
show qos                  # all three objects + service defaults
show qos bindings         # resolved per subscriber, with source
show qos sub <id>         # rates, octets, shaper drops, queue depth
show qos generations      # commit-rebuild drain state
show subscribers          # alias of show qos bindings