Skip to main content
RunBook Academy

VyOSXLV · QoS FundamentalsQoS

DSCP marking — RFC 2474, the DiffServ field, PHB classifications

Advanced⏱ ~18 minconfigurecomparecommitsaverollbacktcpdumptciptables -t mangle

What you'll learn

  • Explain the DSCP field in the IP header (RFC 2474)
  • Distinguish the standard PHB classes (EF, AF, BE, CS)
  • Configure DSCP marking on VyOS (set-mark, match)
  • Recognise the production failure modes of DSCP marking

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15

Not yet marked complete on this device.

DSCP (Differentiated Services Code Point) is a 6-bit field in the IP header (RFC 2474) that allows packets to be marked for QoS treatment. Each DSCP value corresponds to a Per-Hop Behavior (PHB) — the way the packet should be treated at each router (priority, queueing, dropping). DSCP marking is how traffic is classified and prioritized across the network.

This lesson covers what DSCP is at the protocol level, the standard PHB classes, how to configure DSCP marking on VyOS, and the production failure modes.

The DSCP field

The IP header has an 8-bit field at the position previously known as the TOS (Type of Service) byte. The 8 bits are now divided as:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL |Type of Service |          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Within the Type of Service byte:

 0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
|         DSCP          |  ECN  |
+---+---+---+---+---+---+---+---+

The top 6 bits are the DSCP; the bottom 2 bits are ECN (Explicit Congestion Notification, RFC 3168). The DSCP value is 0-63, allowing 64 distinct classes.

Standard PHB classes

The DSCP value defines the PHB (Per-Hop Behavior) — the way the packet should be treated at each router. The standard PHB classes:

EF (Expedited Forwarding)

DSCP value 46 (binary 101110). Used for voice and other latency-critical traffic. EF is intended to be served with the lowest delay and jitter; it’s typically given a strict-priority queue.

AF (Assured Forwarding)

12 DSCP values organised in 4 classes (AF1x, AF2x, AF3x, AF4x) with 3 drop precedences (x = 1, 2, 3):

ClassLow drop (1)Med drop (2)High drop (3)
AF1101214
AF2182022
AF3262830
AF4343638

The class indicates the forwarding priority (AF4 > AF3 > AF2 > AF1); the drop precedence indicates the likelihood of being dropped under congestion (AFx3 > AFx2 > AFx1). E.g., AF31 (DSCP 26) has higher forwarding priority than AF13 (DSCP 14).

BE (Best Effort)

DSCP value 0. The default for unmarked traffic. No special treatment; served on a FIFO basis.

CS (Class Selector)

DSCP values ending in 0: CS0 (0), CS1 (8), CS2 (16), CS3 (24), CS4 (32), CS5 (40), CS6 (48), CS7 (56). Compatible with older IP Precedence; CS7 is the highest. Used for backward compatibility with legacy networks.

flowchart LR
  subgraph HIGH["High priority"]
    EF["EF (46)<br/>voice"]
    CS5["CS5 (40)<br/>legacy voice"]
  end
  subgraph MID["Mid priority"]
    AF41["AF41 (34)"]
    AF31["AF31 (26)"]
    AF21["AF21 (18)"]
  end
  subgraph LOW["Low priority"]
    AF11["AF11 (10)"]
    BE["BE (0)<br/>default"]
  end

Configure DSCP marking on VyOS

DSCP marking on VyOS uses iptables set-mark to set the DSCP value on matching packets. The QoS policy then classifies based on the DSCP.

configure
# Mark VoIP packets with EF (46)
set firewall ipv4 mangle rule 10 action accept
set firewall ipv4 mangle rule 10 description "Mark VoIP with EF"
set firewall ipv4 mangle rule 10 protocol udp
set firewall ipv4 mangle rule 10 destination port 5060
set firewall ipv4 mangle rule 10 set dscp 46

# Mark video conferencing packets with AF41 (34)
set firewall ipv4 mangle rule 20 action accept
set firewall ipv4 mangle rule 20 description "Mark video with AF41"
set firewall ipv4 mangle rule 20 protocol tcp
set firewall ipv4 mangle rule 20 destination port 1720
set firewall ipv4 mangle rule 20 set dscp 34

# Mark bulk transfer packets with BE (0) — explicit
set firewall ipv4 mangle rule 30 action accept
set firewall ipv4 mangle rule 30 description "Mark bulk with BE"
set firewall ipv4 mangle rule 30 protocol tcp
set firewall ipv4 mangle rule 30 destination port 22
set firewall ipv4 mangle rule 30 set dscp 0

commit
save

The configuration uses the mangle table to set the DSCP based on packet match criteria. The matches can be on port, source/destination IP, or other fields.

After marking, the QoS policy uses the DSCP value to classify and queue:

# QoS policy with DSCP-based classes
set qos policy shaper WAN-OUT default bandwidth 1gbit
set qos policy shaper WAN-OUT default burst 15k
set qos policy shaper WAN-OUT default queue-type fq-codel

set qos policy shaper WAN-OUT class voice match dscp 46
set qos policy shaper WAN-OUT class voice priority 0
set qos policy shaper WAN-OUT class voice ceiling 200mbit

set qos policy shaper WAN-OUT class video match dscp 34
set qos policy shaper WAN-OUT class video priority 2
set qos policy shaper WAN-OUT class video ceiling 300mbit

set qos policy shaper WAN-OUT class bulk match all
set qos policy shaper WAN-OUT class bulk priority 7

set interfaces ethernet eth0 traffic-policy out WAN-OUT
commit
save

The QoS policy matches on DSCP value; packets marked with EF go to the voice class; AF41 to the video class; the rest to the bulk class.

Validation

# Verify the mangle rules
show firewall ipv4 mangle
# Lists the marking rules

# Inspect iptables
iptables -t mangle -L -v
# Lists the marking rules with packet counts

# Test with a packet capture
tcpdump -ni eth0 'ip[1] & 0xfc >> 2 == 46'
# Captures only EF-marked packets

# Verify the QoS classes
tc class show dev eth0
# Lists the classes

# Test end-to-end
# Mark a packet on the source host; verify it's marked on capture

A clean validation: the marking rules apply correctly; packets carry the expected DSCP; the QoS policy honours the DSCP; traffic in the corresponding class has the expected treatment.

Production failure modes

Marking not effective

The marking rules are configured, but packets are not marked.

Diagnostic: iptables -t mangle -L -v shows 0 packets matched.

Fix: ensure the rules are correctly matched; check the protocol, ports, and addresses.

Marking at the wrong place

Marking happens at the WAN interface (after the packet leaves the LAN). The marking is too late; the QoS policy on the WAN sees the unmarked packet.

Fix: mark at the LAN interface (or in the mangle table before routing).

DSCP stripped by an intermediate

An intermediate router (firewall, NAT) strips or overwrites the DSCP. The packets arrive at the destination with DSCP 0 (BE).

Diagnostic: capture on the WAN; verify the DSCP on the packets leaving.

Fix: configure the intermediate to preserve DSCP (or re-mark if necessary).

DSCP value conflict

Multiple marking rules apply to the same packet; the later rule overwrites the earlier one. The packet ends up with an unintended DSCP.

Fix: ensure the marking rules are mutually exclusive (different ports/IPs).

Trust-boundary violation

A host on the LAN marks its own DSCP to a high priority, bypassing the trust boundary.

Fix: re-mark all unmarked packets from the LAN to BE; only the trusted router marks traffic.

Rollback

# Enter configuration mode and write the running configuration to a
# file you can load back. `save` is a configuration-mode command that
# takes a path; operational mode has no `| save` pipe.
configure
save /config/pre-change-qos-dscp-TICKET.conf

# Remove the marking rules
delete firewall ipv4 mangle rule 10
delete firewall ipv4 mangle rule 20
delete firewall ipv4 mangle rule 30

# Read the diff before committing anything
compare
commit

# Or restore a previous configuration
load /config/pre-change-qos-dscp-TICKET.conf
commit
save

The rollback removes the marking; packets are not marked; the QoS policy may treat them all as BE.

Production discipline

Cross-course references

  • Part XLV-01 (XLV-VyOS-QoS / concept) covers the overall QoS pipeline.
  • Part XLV-03 (XLV-VyOS-QoS / classification) covers packet classification.
  • Part XLV-05 (XLV-VyOS-QoS / trust boundaries) covers the trust-boundary discipline.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the DSCP value for EF (Expedited Forwarding), and which traffic is it typically used for?

  2. Q2. DSCP marking must happen at the trust boundary (e.g., the LAN-facing interface of the router), not on the WAN-facing interface or by hosts themselves.

  3. Q3. An operator configures DSCP marking on the WAN interface (the egress interface towards the Internet). The marking rules apply, but the QoS policy on the LAN-facing interface does not see the marked packets. What is the issue?

    The operator configures marking on the WAN interface (eth0). The rules mark VoIP packets with DSCP 46. The packets are marked after they leave the LAN; the QoS policy on the LAN-facing interface (eth1) does not see the marked packets. The QoS policy on the LAN interface treats all packets as BE; the LAN is congested; voice suffers.

  4. Q4. An operator marks voice traffic with DSCP 46 on the LAN. However, a stateful firewall in the path strips the DSCP. The voice traffic arrives at the destination with DSCP 0 (BE). What is the fix?

    The operator marks voice traffic at the LAN interface. The packets leave the LAN with DSCP 46. They pass through a stateful firewall (e.g., a third-party firewall in the path). The firewall strips the DSCP (some stateful firewalls do this for traffic-classification purposes). The packets arrive at the remote side with DSCP 0 (BE); the QoS policy on the remote side does not give them priority.

Passing score: 75%. Answers are checked in this browser.