fault-report :: upstream-dscp :: rev 2 :: 2026-10-31

> ISP throttles upstream DSCP CS1 traffic

Home network fault report. 2 Gbps symmetric fiber line. UniFi Dream Machine Pro gateway.
STATUS: WORKAROUND ACTIVE PERSISTENCE: ACTIVE FIRMWARE-UPDATE TEST: PENDING
CS1 upload, before
2 Mbps
CS1 upload, after
1,811 Mbps
Fault location
ISP past WAN port
Self-repair time
≤60 s

Live speed test

  speedtest :: browser → cloudflare edge
IDLE
--Mbps
Latency (idle)
-- ms
Jitter
-- ms
Download
-- Mbps
Upload
-- Mbps
$ ready. Push RUN TEST.

The test sends data between this browser and the nearest Cloudflare server. It uses approximately 0.5–2 GB on a fast line. Browsers cannot set DSCP marks, so this test measures unmarked traffic only. Results show the speed of the device and network that you use now.

Summary

The ISP slows all upstream packets that have the DSCP mark CS1. The limit is approximately 1–2 Mbps. The ISP also slows the mark AF12 to approximately 25 Mbps. Other marks are not affected. Downloads are not affected.

OpenSSH on Linux uses the mark CS1 for bulk transfers. Thus, scp, rsync and other SSH uploads from the LAN were almost stopped.

The gateway now clears all DSCP marks on the WAN port. A timer on the gateway applies this setting again after each reboot. The Linux hosts also do not set DSCP marks on SSH traffic now. CS1 uploads operate at the full line rate.

Symptom

We sent the same upload with different DSCP marks. We sent each test in the same minute. Only the mark changed.

none (0x00)
520
LE (0x04)
573
CS1 (0x20)
2
DSCP 9 (0x24)
445
AF11 (0x28)
690
AF12 (0x30)
26
AF13 (0x38)
363
CS2 (0x40)
370
AF21 (0x48)
654
Single-stream HTTPS upload to speed.cloudflare.com. Values in Mbps. Single-stream results vary by ±30% between tests.

The limit applies to exact DSCP values. DSCP 9 is adjacent to CS1, but it operates at full speed. Thus, the cause is a classifier that looks for specific values.

It is a shaper, not a drop

CS1 pings to 1.1.1.1 had 0% loss. But large CS1 pings had more delay:

PingMarkAvg RTT
1400 bytesnone2.4 ms
1400 bytesCS111.8 ms

The added delay is approximately 10 ms for one 1428-byte packet. This agrees with a queue that drains at approximately 1 Mbps.

Fault location

We captured packets on the gateway with tcpdump. We recorded the time of each CS1 packet at each interface.

LAN hosttos 0x20
Gateway LAN intos 0x20
Gateway WAN out+50 µs · tos 0x20
ISP+11 ms RTT (CS1)
+2 ms RTT (none)

Probable cause

We cannot see the ISP configuration. The data agrees with this explanation:

Items that we eliminated

ItemResult
Smart Queues (SQM)OFF on all WANs
Traffic rules / QoS rulesNone
Custom firewall policiesNone
DSCP rules in iptables / nftablesNone
Gateway queue disciplinesDefault only (mq + pfifo_fast)
Intrusion Prevention (IPS)OFF/ON test: no change
Path MTUClean (1472-byte DF ping passes)
Line capacity (unmarked)~2 Gbps up and down

Workaround 1: gateway

The gateway kernel does not have a DSCP rewrite module. The iptables DSCP target, act_pedit and dsmark are all not available. The cake queue discipline is available. Its wash option clears the DSCP field on egress.

One cake instance on the WAN root limited the line to approximately 1.25 Gbps. One CPU core did all the work. Thus, we put one cake instance on each of the four transmit queues:

  gateway :: root shell
# one cake instance per TX queue, DSCP wash, no rate limit
# modprobe sch_cake
# tc qdisc replace dev <wan> root handle 1: mq
# for q in 1 2 3 4; do
    tc qdisc replace dev <wan> parent 1:$q cake unlimited besteffort wash
  done

# revert to the default
# tc qdisc del dev <wan> root

A packet capture shows the result. A CS1 packet enters the gateway with tos 0x20. It leaves the WAN port with tos 0x00.

Persistence

A reboot, a firmware update or a change to the WAN settings removes the queue setting. Thus, we installed a systemd timer on the gateway:

Self-repair test: We removed the setting manually. The timer applied it again after 54 s.

Workaround 2: Linux hosts

Each Linux host on the LAN now has this OpenSSH client setting:

  /etc/ssh/ssh_config.d/50-ipqos-none.conf
IPQoS none

SSH then sends unmarked packets. This setting gives protection if the gateway setting is not there. The base build script for new hosts also includes it.

Verification: on/off test

We removed the workaround and then installed it again, in the same minute.

WorkaroundnoneCS1AF12
Removed520226
Installed401335653
Installed (second LAN host)452279464
Single-stream upload, Mbps.

Verification: sustained load

TestAvg10 s min–maxData
CS1, 1 stream, 60 s398363–4283.0 GB
CS1, 4 streams, 120 s1,3021,190–1,45219.5 GB
none, 4 streams, 60 s1,3431,226–1,43010.1 GB
Single cake instance. Mbps. Ping RTT under load: 3.4–4.7 ms avg.

Verification: ceiling

We used 18 parallel uploads (6 processes × 3 streams) for 45–60 s per test. The LAN host has a 2.5 GbE link.

default, none
2,059
1× cake, none
1,241
1× cake, CS1
1,564
4× cake, none
2,010
4× cake, CS1
1,811
Aggregate upload, Mbps. Best run of each configuration. Repeat runs of 4× cake gave 1,527–1,811 (CS1) and 1,797–2,010 (none). The variation comes from the remote test server.

Open items

  1. Make sure that the timer is there after the next gateway firmware update. If it is not there, install it again.
  2. Do a real SSH upload test from a second LAN host with -o IPQoS=cs1. Status: pending.

Decision: The owner will not send a fault report to the ISP. The workaround stays in place.

Method