QoS Configuration
Configure per-subscriber traffic shaping with CAKE qdisc.
Overview
The qos section configures Quality of Service (QoS) via CAKE (Common Applications Kept Enhanced):
- Per-subscriber rate limiting (download and upload)
- Overhead profile adjustment for different encapsulations
- Ingress shaping via a per-session Intermediate Functional Block (IFB) device
- Integration with RADIUS for per-subscriber and dynamic rate changes
Downstream (to subscriber) shaping is an egress CAKE qdisc on the subscriber's
access interface — the demux VLAN for DHCP/IPoE (e.g. sub0.1234.2) or the ppp
interface for PPPoE (e.g. ppp0). Upstream (from subscriber) shaping is applied
on a per-session IFB device named ifb<session_id> (e.g. ifb10).
Configuration Options
enabled
Enable or disable QoS (optional).
qos:
enabled: true
Type: Boolean
Required: No
Default: false
Valid values: true, false
CLI:
abng# set qos enabled true
default_down
Default download rate for subscribers (optional).
qos:
default_down: "100mbit"
Type: String (bandwidth format)
Required: No
Default: None
Format: <number><unit> (e.g., "100mbit", "1gbit", "50kbit")
Valid units: kbit, mbit, gbit
CLI:
abng# set qos default_down "100mbit"
default_up
Default upload rate for subscribers (optional).
qos:
default_up: "40mbit"
Type: String (bandwidth format)
Required: No
Default: None
Format: <number><unit> (e.g., "40mbit", "1gbit", "10kbit")
Valid units: kbit, mbit, gbit
CLI:
abng# set qos default_up "40mbit"
default_overhead_profile
Default overhead profile for CAKE (optional).
qos:
default_overhead_profile: "pppoe_ethernet"
Type: String
Required: No
Default: "pppoe_ethernet"
Valid values: Key from overhead_profiles
Purpose: Adjusts CAKE overhead calculation for the encapsulation type.
CLI:
abng# set qos default_overhead_profile "pppoe_ethernet"
overhead_profiles
Custom overhead profiles for different encapsulations (optional).
qos:
overhead_profiles:
pppoe_ethernet:
overhead: 34
mpu: 64
ipoe_ethernet:
overhead: 22
mpu: 64
Profile Options
overhead
Overhead bytes for the encapsulation (required).
overhead_profiles:
pppoe_ethernet:
overhead: 34
Type: Integer
Required: Yes
Constraints: Non-negative integer
Calculation:
- PPPoE: 8 bytes (PPPoE header) + 2 bytes (PPP header) + 20 bytes (IP header) + 4 bytes (FCS) = 34 bytes
- IPoE: 14 bytes (Ethernet) + 4 bytes (FCS) + 4 bytes (VLAN) = 22 bytes
mpu
Minimum Packet Unit (optional).
overhead_profiles:
pppoe_ethernet:
mpu: 64
Type: Integer
Required: No
Default: 64
Constraints: Non-negative integer
Purpose: Minimum size for rate calculation (prevents underestimation of small packets).
Example Configurations
Minimal QoS Configuration
qos:
enabled: true
default_down: "100mbit"
default_up: "40mbit"
Uses default overhead profile (pppoe_ethernet).
Full QoS Configuration
qos:
enabled: true
default_down: "100mbit"
default_up: "40mbit"
default_overhead_profile: "pppoe_ethernet"
overhead_profiles:
pppoe_ethernet:
overhead: 34
mpu: 64
ipoe_ethernet:
overhead: 22
mpu: 64
pppoe_qinq:
overhead: 38
mpu: 64
Different Rates by Service
pppoe:
enabled: true
dhcp:
enabled: true
qos:
enabled: true
default_down: "100mbit"
default_up: "40mbit"
default_overhead_profile: "pppoe_ethernet"
overhead_profiles:
pppoe_ethernet:
overhead: 34
mpu: 64
ipoe_ethernet:
overhead: 22
mpu: 64
Configuration via CLI
Enable QoS
abng> configure
abng# set qos enabled true
abng# commit
Set Default Rates
abng# set qos default_down "100mbit"
abng# set qos default_up "40mbit"
abng# commit
Set Overhead Profile
abng# set qos default_overhead_profile "pppoe_ethernet"
abng# commit
Add Custom Overhead Profile
abng# set qos overhead_profiles custom_profile overhead 40
abng# set qos overhead_profiles custom_profile mpu 64
abng# commit
Verification
View QoS Configuration
abng> show configuration | match "^qos:"
qos:
enabled: true
default_down: 100mbit
default_up: 40mbit
default_overhead_profile: pppoe_ethernet
overhead_profiles:
pppoe_ethernet:
overhead: 34
mpu: 64
View Applied QoS Policy
abng> show qos
┌────┬──────────────┬─────────────┬──────┬──────┬────────────────┬────┬───────┐
│ ID ┆ Username ┆ Interface ┆ Down ┆ Up ┆ Profile ┆ OH ┆ IFB │
│ 1 ┆ - ┆ sub0.1234.2 ┆ 250M ┆ 100M ┆ ipoe_ethernet ┆ 22 ┆ ifb1 │
│ 10 ┆ testuser@isp ┆ ppp0 ┆ 250M ┆ 100M ┆ pppoe_ethernet ┆ 34 ┆ ifb10 │
└────┴──────────────┴─────────────┴──────┴──────┴────────────────┴────┴───────┘
View Live Throughput
abng> show qos statistics
┌────┬──────────────┬─────────────┬────────┬──────┬─────────┬─────────────┬─────────┬─────────┐
│ ID ┆ Username ┆ Interface ┆ Dir ┆ Rate ┆ Current ┆ Transferred ┆ Dropped ┆ Backlog │
│ 1 ┆ - ┆ sub0.1234.2 ┆ ▼ down ┆ 250M ┆ 46Kbps ┆ 3.1 MB ┆ 0 ┆ 0 │
│ ┆ ┆ ┆ ▲ up ┆ 100M ┆ 1Kbps ┆ 2.1 KB ┆ 0 ┆ 0 │
└────┴──────────────┴─────────────┴────────┴──────┴─────────┴─────────────┴─────────┴─────────┘
Current is a 5-second average sampled and cached by abng-qos from the CAKE
qdiscs — live throughput for shaped sessions only. For cumulative
per-session totals across all sessions (including unmetered ones), see the
per-session accounting counters (Bytes In / Bytes Out) in show subscribers detail and over SNMP, described in
Subscriber Sessions — Per-Session Accounting.
See also the
operational-mode CLI reference.
Check CAKE Qdisc
tc qdisc show
qdisc cake 8001: dev ppp0 root refcnt 2 bandwidth 100Mbit diffserv4 ...
qdisc cake 8002: dev ifb10 root refcnt 2 bandwidth 100Mbit diffserv4 ...
Check abng-qos Logs
sudo journalctl -u abng-qos -f
Integration with RADIUS
QoS rates come from RADIUS per-subscriber via the Athena vendor-specific attributes (VSAs):
radius:
servers:
- host: "10.255.0.10"
secret: "your-secret"
RADIUS attributes:
- Athena-Rate-Down — Download rate (e.g., "250mbit")
- Athena-Rate-Up — Upload rate (e.g., "100mbit")
Values are strings like "250mbit"/"100mbit"; the parser also accepts gbit,
kbit, and plain bps. This applies to both DHCP/IPoE and PPPoE.
A subscriber with no rate attribute (no plan) is left unmetered — abng-qos skips shaping when the rate is 0 rather than applying a 0-bandwidth qdisc.
RADIUS response example:
Athena-Rate-Down = "250mbit"
Athena-Rate-Up = "100mbit"
Overhead Profile Reference
PPPoE over Ethernet (Standard)
pppoe_ethernet:
overhead: 34
mpu: 64
Breakdown:
- Ethernet frame: 14 bytes (dst MAC 6 + src MAC 6 + type 2)
- PPPoE header: 6 bytes (version/type 1 + code 1 + session ID 2 + length 2)
- PPP header: 2 bytes (protocol 2)
- IP header: 20 bytes (minimum)
- FCS: 4 bytes (frame check sequence)
- Total: 46 bytes (rounded to 34 for typical usage)
IPoE over Ethernet
ipoe_ethernet:
overhead: 22
mpu: 64
Breakdown:
- Ethernet frame: 14 bytes
- VLAN tag: 4 bytes
- FCS: 4 bytes
- Total: 22 bytes
PPPoE over QinQ
pppoe_qinq:
overhead: 38
mpu: 64
Breakdown:
- Ethernet: 14 bytes
- Outer VLAN: 4 bytes
- Inner VLAN: 4 bytes
- PPPoE: 6 bytes
- PPP: 2 bytes
- IP: 20 bytes
- FCS: 4 bytes
- Total: 54 bytes (rounded to 38)
Validation Rules
| Field | Validation |
|---|---|
enabled | Boolean |
default_down | Valid bandwidth format (e.g., "100mbit") |
default_up | Valid bandwidth format (e.g., "40mbit") |
default_overhead_profile | Must exist in overhead_profiles |
overhead_profiles[].overhead | Non-negative integer |
overhead_profiles[].mpu | Non-negative integer |
Best Practices
- Default Rates — Set reasonable defaults for your subscriber base
- Overhead Profile — Match your actual encapsulation (PPPoE vs IPoE)
- RADIUS Override — Use RADIUS for per-subscriber rate customization
- Monitoring — Monitor CAKE qdisc stats for congestion
- Testing — Test with
iperfto verify rates - Ingress Shaping — Enable IFB for ingress (upload) shaping
- Documentation — Document your overhead calculations
Troubleshooting
QoS Not Applying
- Check QoS is enabled:
show configuration | match qos - Check CAKE qdisc exists:
tc qdisc show - Check abng-qos logs:
journalctl -u abng-qos -f - Check session is active:
show subscribers
Rates Not Matching Expected
- Check overhead profile:
show configuration | match overhead_profiles - Verify with
iperf:iperf -c <subscriber-ip> -t 10 - Check CAKE stats:
tc -s qdisc show dev ppp0 - Adjust overhead if needed
IFB Ingress Shaping Not Working
- Check IFB device exists:
ip link show | grep ifb(per-sessionifb<id>) - Check ingress qdisc:
tc qdisc show dev ifb<session_id> - Check abng-qos logs:
journalctl -u abng-qos -f
Next Steps
- CGNAT Configuration — Carrier-Grade NAT
- Routing Configuration — BGP and OSPF
- Configuration Overview — All configuration sections