Skip to main content

QoS/CAKE

Per-subscriber traffic shaping with CAKE qdisc.

Overview

AthenaBNG applies per-subscriber QoS using CAKE (Common Applications Kept Enhanced), a modern qdisc that provides:

  • Fair bandwidth allocation
  • Low latency
  • Automatic overhead calculation
  • Per-flow fairness
  • Built-in SQM (Smart Queue Management)

Shaping Direction

Each shaped subscriber gets CAKE in both directions:

  • Downstream (to subscriber) — an egress CAKE qdisc on the subscriber's access interface. For DHCP/IPoE this is the demux VLAN (e.g. sub0.1234.2); for PPPoE it is the ppp interface (e.g. ppp0).
  • Upstream (from subscriber) — ingress shaping via a per-session IFB (Intermediate Functional Block) device named ifb<session_id> (e.g. ifb10), with traffic redirected from the access interface to the IFB.

Rates come from RADIUS (see Per-Subscriber Rates). A subscriber with no rate plan is left unmetered: abng-qos skips shaping when the rate is 0 rather than applying a 0-bandwidth qdisc. This applies to both DHCP/IPoE and PPPoE.

CAKE Qdisc

CAKE is a modern replacement for fq_codel that:

  • Automatically detects and isolates flows
  • Provides fair bandwidth allocation
  • Reduces latency and jitter
  • Handles overhead calculation
  • Supports diffserv (QoS classes)

CAKE Parameters

tc qdisc add dev ppp0 root cake \
bandwidth 100Mbit \
overhead 34 \
mpu 64 \
rtt 20ms \
ack-filter \
split-gst \
diffserv4 \
nat \
nowash
ParameterValuePurpose
bandwidthRateDownload/upload rate
overheadBytesEncapsulation overhead
mpuBytesMinimum packet unit
rttTimeRound-trip time estimate
ack-filterFilter duplicate ACKs
split-gstSplit GST (get-set-test)
diffserv44-class QoS
natNAT detection
nowashDisable wash

Overhead Profiles

Different encapsulations require different overhead calculations:

PPPoE over Ethernet

pppoe_ethernet:
overhead: 34
mpu: 64

Breakdown:

  • Ethernet: 14 bytes
  • PPPoE: 6 bytes
  • PPP: 2 bytes
  • IP: 20 bytes (minimum)
  • FCS: 4 bytes
  • Total: 46 bytes (rounded to 34)

IPoE over Ethernet

ipoe_ethernet:
overhead: 22
mpu: 64

Breakdown:

  • Ethernet: 14 bytes
  • VLAN: 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)

Ingress Shaping

For upload rate limiting, abng-qos creates a per-session IFB (Intermediate Functional Block) device named ifb<session_id> (e.g. ifb10 for session 10):

# Create per-session IFB device
ip link add ifb10 type ifb

# Bring up IFB
ip link set ifb10 up

# Redirect ingress to IFB
tc filter add dev ppp0 parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev ifb10

# Apply CAKE to IFB
tc qdisc add dev ifb10 root cake bandwidth 100Mbit ...

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

Per-Subscriber Rates

Rates come from RADIUS via the Athena vendor-specific attributes Athena-Rate-Down and Athena-Rate-Up:

Athena-Rate-Down = "250mbit"
Athena-Rate-Up = "100mbit"

Values are strings like "250mbit"/"100mbit"; the parser also accepts gbit, kbit, and plain bps. This applies to both DHCP/IPoE and PPPoE sessions.

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 that would black-hole the subscriber.

Default Rates

If no RADIUS rate is supplied, configured defaults can be applied:

qos:
default_down: "100mbit"
default_up: "40mbit"

Dynamic Rate Changes (CoA)

RADIUS server can change rates on-the-fly:

Acct-Session-Id = "abng-1709312400-1"
Athena-Rate-Down = "25mbit"
Athena-Rate-Up = "10mbit"

abng-qos applies new rates without packet loss.

Monitoring

View Applied QoS Policy

abng> show qos

Shows the per-session applied policy: ID, Username, Interface, Down, Up, Profile, OH (overhead bytes), and IFB device.

View Live Throughput

abng> show qos statistics

(show qos stats is an alias.) Shows live per-session, per-direction throughput: the configured Rate, the Current throughput (a 5-second average), Transferred bytes, Dropped, and Backlog. abng-qos samples all CAKE qdiscs every 5 seconds and caches the result, so this is a fast in-memory read. The same counters are also available via tc -s qdisc show dev <iface> and over SNMP.

This is live throughput for shaped sessions only (it comes from the CAKE qdiscs). For cumulative per-session totals across all sessions — including unmetered ones — see the per-session accounting counters (Bytes In / Bytes Out) shown by show subscribers detail and over SNMP, described in Subscriber Sessions — Per-Session Accounting.

Check CAKE Qdisc

tc qdisc show
tc -s qdisc show dev ppp0

View IFB Devices

ip link show | grep ifb

Monitor abng-qos Logs

sudo journalctl -u abng-qos -f

Testing

Verify Download Rate

# From subscriber
iperf -c <bng-ip> -t 10 -R

Verify Upload Rate

# From subscriber
iperf -c <bng-ip> -t 10

Check Latency

# From subscriber
ping <bng-ip>

Troubleshooting

QoS Not Applying

  1. Check QoS is enabled: show configuration | match qos
  2. Check CAKE qdisc exists: tc qdisc show
  3. Check abng-qos logs: journalctl -u abng-qos -f
  4. Check session is active: show subscribers

Rates Not Matching Expected

  1. Check overhead profile: show configuration | match overhead_profiles
  2. Verify with iperf: iperf -c <subscriber-ip> -t 10
  3. Check CAKE stats: tc -s qdisc show dev ppp0
  4. Adjust overhead if needed

IFB Ingress Shaping Not Working

  1. Check IFB device exists: ip link show | grep ifb (per-session ifb<id>)
  2. Check ingress qdisc: tc qdisc show dev ifb<session_id>
  3. Check abng-qos logs: journalctl -u abng-qos -f

Best Practices

  1. Overhead Profile — Match your actual encapsulation
  2. Default Rates — Set reasonable defaults for your subscriber base
  3. RADIUS Override — Use RADIUS for per-subscriber customization
  4. Testing — Test with iperf to verify rates
  5. Monitoring — Monitor CAKE stats for congestion
  6. Ingress Shaping — Enable IFB for upload rate limiting
  7. Documentation — Document your overhead calculations

Next Steps