Role subpackages set the system-wide default qdisc and TCP congestion control via /usr/lib/sysctl.d, without pulling in the base package: server fq + bbr bare metal, VM guests vmhost fq_codel + bbr hypervisors, container hosts router fq_codel + cubic desktop fq_codel + cubic The base package applies cake per interface from /etc/qos-profiles/<iface>.conf, layered over role defaults and /etc/qos-profiles/defaults.conf: - LINK_RATE with per-direction overrides, shaped to SHAPE_PERCENT (default 95, per direction overridable) - outbound fairness per source host and diffserv4; inbound via ifb, fairness per destination host, besteffort with DSCP wash - NAT awareness, extra cake args (shared and per direction), raw qdisc overrides - config parsed without executing it, validated before any change, previous state undone on each run Applied by the qos-profiles@<iface> unit (bound to the device) or the qos-profiles-networkmanager dispatcher subpackage, installed automatically on hosts with NetworkManager. Includes ready-made examples for VM hosts, OVH dual-NIC servers, DC and home routers.
qos-profiles
Default qdisc and TCP congestion control per machine role, plus optional per-interface qdiscs (cake, with ifb for inbound traffic).
Roles
Install exactly one role subpackage:
| Subpackage | default_qdisc | congestion control | cake NAT | Use for |
|---|---|---|---|---|
qos-profiles-server |
fq | bbr | no | bare-metal servers without guests, VM guests |
qos-profiles-vmhost |
fq_codel | bbr | no | hypervisors, container hosts |
qos-profiles-router |
fq_codel | cubic | yes | routers |
qos-profiles-desktop |
fq_codel | cubic | no | workstations |
The sysctl file is /usr/lib/sysctl.d/60-qos-profiles-<role>.conf; override it
in /etc/sysctl.d/. default_qdisc only applies to interfaces created after
it is set, so reboot after installing or switching roles. Congestion control
is system-wide (or per route), not per interface.
Per-interface qdiscs
Needs the qos-profiles package; the role packages don't pull it in.
Create /etc/qos-profiles/<iface>.conf, see
/usr/share/qos-profiles/example.conf for all variables and
/usr/share/qos-profiles/examples/ for ready-made setups:
| Example | Setup |
|---|---|
defaults.conf |
site-wide /etc/qos-profiles/defaults.conf |
vmhost-routed-uplink.conf |
VM host, guests routed via the host uplink (EVPN) |
vmhost-egress-only.conf |
VM host, outbound fairness only at NIC line rate |
vmhost-nat-guests.conf |
VM/container host with masqueraded guests |
ovh-public.conf |
dual-NIC dedicated server, public NIC |
ovh-vrack-private.conf |
private NIC capped by the provider, outbound only |
dc-router-transit.conf |
datacenter router, transit uplink, no NAT |
router-ftth.conf |
fibre with Ethernet handoff, NAT |
router-vdsl-pppoe.conf |
VDSL2 with PPPoE on ppp0, NAT, ACK filtering |
router-docsis.conf |
cable, NAT, ACK filtering |
backup-nic-raw.conf |
raw fq qdisc with a per-flow cap instead of cake |
Minimal example:
LINK_RATE=1gbit
This shapes both directions to 95% of the link rate with cake. Outbound,
traffic is shared per source host and DiffServ classes are applied
(diffserv4). Inbound, traffic is shared per destination host, DSCP marks
are ignored (besteffort) and cleared (wash), since they come from the
internet. EGRESS_SHAPE_PERCENT and INGRESS_SHAPE_PERCENT set the
percentage per direction.
Configuration is read in order, later overriding earlier:
/usr/lib/qos-profiles/role-<role>.conf— installed role package/etc/qos-profiles/defaults.conf— site-wide/etc/qos-profiles/<iface>.conf— the interface
It is applied by either:
qos-profiles-networkmanager(installed automatically with NetworkManager) when NetworkManager brings the interface up, orsystemctl enable --now qos-profiles@<iface>for interfaces NetworkManager doesn't manage. It runs whenever the device appears.
Both may be active; they're serialised and idempotent. To apply changes run
systemctl restart qos-profiles@<iface> or
/usr/libexec/qos-profiles/qos-apply start <iface>. Stopping restores the
default qdisc and removes the ifb device.
Inbound shaping replaces any existing clsact qdisc on the interface (and its
tc/BPF filters).
DiffServ
diffserv4 sorts outbound packets by DSCP into bulk (CS1), best effort, video
(AF4x, CS3, ...) and voice (EF, CS6, ...). Higher classes get priority only up
to a share of the rate, so they can't starve the others. Marking backup or
replication traffic CS1 (e.g. nftables ip dscp set cs1) makes it yield to
everything else.
Topologies
- VM host, VMs routed via the host uplink (EVPN anycast gateway): cake on the uplink NIC gives each guest an equal share. VXLAN-encapsulated traffic on the same NIC is seen by its outer header (the VTEP address), so it shares as a single host.
- VM host, VMs bridged to a switch, routing elsewhere: the WAN bottleneck
is at the router; put cake on the router WAN (
qos-profiles-router). The host only needs the role package. - Host with separate public and private NICs: configure the public NIC only.
- Bond or VLAN uplink: these devices have no queue of their own; put cake on the physical NIC, or set a rate explicitly.