Skip to content

traffic control

Thomas Mangin edited this page Jul 26, 2026 · 3 revisions

Pre-Alpha. This page describes behavior that may change.

Ze programs per-interface queueing disciplines, classes, and filters from a single traffic-control { } YANG section. The same config is consumed by two backends; the operator chooses one via the backend leaf.

Backends

Backend Platform Default Mechanism
tc Linux yes vishvananda/netlink tc calls (HTB, HFSC, FQ, TBF, netem, ...)
vpp Linux with VPP no GoVPP binary API (policers, QoS egress maps)

Configuration

traffic-control {
    backend tc;
    interface eth0 {
        qdisc {
            type htb;
            class fast {
                rate 10mbit;
                ceil 20mbit;
            }
        }
    }
}

The tc backend and the existing root qdisc

Ze snapshots the interface's original root qdisc before installing its own, so the interface can be restored exactly. A qdisc the backend cannot reproduce is refused rather than approximated, and the commit fails naming it.

noqueue is accepted, and matters: it is the default root on every virtual interface (veth, dummy, bridge, anything the kernel gives no real queue), so it is the state a QoS config is most often applied from, not a corner case. It is exactly restorable despite carrying no reconstructable parameters, because it is the absence of a discipline: restore deletes whatever root Ze installed rather than replacing it, which returns the interface to noqueue. Container and VM deployments previously failed the apply with qdisc "noqueue" cannot be snapshotted exactly by backend tc.

Other generic qdiscs (mq, clsact, and so on) stay rejected, because those do carry state this backend cannot reproduce.

Filter priorities

The kernel keeps exactly one filter instance per (parent, priority) pair, and that instance carries a single link-layer protocol. Ze therefore allocates a distinct priority per protocol: the IPv4 (ETH_P_IP) and IPv6 (ETH_P_IPV6) halves of a DSCP or protocol match no longer share one priority, and neither does a mark filter (ETH_P_ALL). With a shared priority the kernel accepted the first filter and refused the second outright.

VPP backend compatibility

The VPP backend rejects qdisc and filter types that cannot be represented faithfully in VPP. Rejection fires at ze config commit with a descriptive error.

qdisc type vpp Notes
htb with exactly 1 class accepted One policer: CIR = Rate kbps, EIR = Ceil kbps (2R3C RFC 2698).
tbf with exactly 1 class accepted One policer: CIR = EIR = Rate kbps (1R2C).
htb / tbf with 0 or >1 classes rejected Multi-class shaping needs filter-based classification (deferred).
prio rejected Class-index to DSCP-value mapping needs explicit design.
hfsc, fq, sfq, fq_codel, netem rejected No VPP equivalent.

All filter types are currently rejected under the VPP backend.

Operational notes

  • VPP must be running when traffic-control config applies. If VPP is not reachable, Apply waits up to 5 seconds and then fails the commit.
  • Rates round up. Ze uses bps internally; VPP uses kbps.
  • Interface must exist in VPP. Unknown interface names fail the apply.

See also

Adapted from main/docs/guide/traffic-control.md.

Home

About

First Steps

Configuration

Operation

Interfaces

Plugins

Plugin Development

Chaos Testing

Blueprints

Development

Reference

Clone this wiki locally