Introduction
Quality of Service (QoS) is the mechanism by which a network device identifies, classifies, and applies differential treatment to traffic flows. Without QoS, all packets compete equally for bandwidth — a video conference can be starved by a bulk file transfer sharing the same WAN link. On Cisco IOS and IOS-XE platforms, the Modular QoS CLI (MQC) provides a structured, three-step framework: classify traffic with class-maps, define actions with policy-maps, and apply policies to interfaces with service-policy commands.
This run book covers the complete MQC workflow on routers and switches running IOS/IOS-XE (ASR 1000, ISR 4000, Catalyst 9000), using hostnames and domain names consistent with InfraRunBook lab conventions.
Lab Topology
All examples use the following topology:
- rtr-infrarunbook-core — ASR 1001-X, IOS-XE 17.x (WAN-facing router)
- sw-infrarunbook-dist01 — Catalyst 9300 (distribution switch)
- WAN uplink:
GigabitEthernet0/0/0
, 100 Mbps committed, 150 Mbps burst - LAN downlink:
GigabitEthernet0/0/1
- Management:
10.10.0.0/24
, Voice VLAN:10.20.0.0/24
, Data VLAN:10.30.0.0/24
Understanding DSCP and Per-Hop Behaviours
Differentiated Services Code Point (DSCP) is a 6-bit field in the IP header (bits 0–5 of the ToS byte). It defines a Per-Hop Behaviour (PHB) — the treatment a packet receives at each router. The most important PHBs are:
- EF (Expedited Forwarding, DSCP 46 / 0x2E) — low latency, low jitter; ideal for VoIP RTP streams
- AF (Assured Forwarding) classes AF11–AF43 — four classes, three drop precedences per class; used for transactional and streaming data
- CS (Class Selector) 0–7 — backward-compatible with IP Precedence
- Default (BE, DSCP 0) — best-effort, drop-tail treatment
The table below maps common application types to recommended DSCP values used throughout this guide:
- VoIP bearer (RTP): EF (46)
- VoIP signalling (SIP): CS3 (24)
- Video conferencing: AF41 (34)
- Business-critical data: AF21 (18)
- Bulk / backup: CS1 (8)
- Best effort / scavenger: Default (0)
Step 1 — Define Class-Maps
Class-maps match traffic using
matchstatements. Use
match-any(logical OR) or
match-all(logical AND). Best practice is to start with DSCP-based matching for traffic that is already marked upstream (e.g., by IP phones), and ACL-based matching for unmarked traffic.
Class-Map for VoIP RTP (already marked EF by IP phone)
rtr-infrarunbook-core(config)# class-map match-any CM-VOICE-RTP
rtr-infrarunbook-core(config-cmap)# match dscp ef
rtr-infrarunbook-core(config-cmap)# description VoIP RTP bearer - matched by EF DSCP
rtr-infrarunbook-core(config-cmap)# exit
Class-Map for VoIP Signalling (SIP on TCP/UDP 5060 and 5061)
rtr-infrarunbook-core(config)# ip access-list extended ACL-VOIP-SIG
rtr-infrarunbook-core(config-ext-nacl)# permit tcp 10.20.0.0 0.0.0.255 any eq 5060
rtr-infrarunbook-core(config-ext-nacl)# permit udp 10.20.0.0 0.0.0.255 any eq 5060
rtr-infrarunbook-core(config-ext-nacl)# permit tcp 10.20.0.0 0.0.0.255 any eq 5061
rtr-infrarunbook-core(config-ext-nacl)# exit
rtr-infrarunbook-core(config)# class-map match-any CM-VOICE-SIG
rtr-infrarunbook-core(config-cmap)# match access-group name ACL-VOIP-SIG
rtr-infrarunbook-core(config-cmap)# description SIP signalling from infrarunbook-prod voice VLAN
rtr-infrarunbook-core(config-cmap)# exit
Class-Map for Business-Critical Data (SAP, custom ERP on TCP 8443)
rtr-infrarunbook-core(config)# ip access-list extended ACL-BIZ-CRITICAL
rtr-infrarunbook-core(config-ext-nacl)# permit tcp 10.30.0.0 0.0.0.255 host 203.0.113.50 eq 8443
rtr-infrarunbook-core(config-ext-nacl)# permit tcp 10.30.0.0 0.0.0.255 host 203.0.113.51 eq 8443
rtr-infrarunbook-core(config-ext-nacl)# exit
rtr-infrarunbook-core(config)# class-map match-any CM-BIZ-CRITICAL
rtr-infrarunbook-core(config-cmap)# match access-group name ACL-BIZ-CRITICAL
rtr-infrarunbook-core(config-cmap)# match dscp af21
rtr-infrarunbook-core(config-cmap)# exit
Class-Map for Bulk / Backup Traffic
rtr-infrarunbook-core(config)# ip access-list extended ACL-BULK
rtr-infrarunbook-core(config-ext-nacl)# permit tcp any any eq 445
rtr-infrarunbook-core(config-ext-nacl)# permit tcp any any eq 2049
rtr-infrarunbook-core(config-ext-nacl)# permit tcp 10.30.0.0 0.0.0.255 host 10.10.0.100 eq 9100
rtr-infrarunbook-core(config-ext-nacl)# exit
rtr-infrarunbook-core(config)# class-map match-any CM-BULK
rtr-infrarunbook-core(config-cmap)# match access-group name ACL-BULK
rtr-infrarunbook-core(config-cmap)# match dscp cs1
rtr-infrarunbook-core(config-cmap)# exit
Step 2 — Define Policy-Maps (Marking, Policing, Shaping, Queuing)
Policy-maps are where actions are assigned to each class. On the WAN egress interface, a hierarchical policy-map (H-QoS) is used: a parent policy shapes the aggregate to the committed WAN rate, while a child policy applies per-class treatment.
Child Policy-Map: Per-Class Queuing and Marking
rtr-infrarunbook-core(config)# policy-map PM-CHILD-WAN-EGRESS
! ── VoIP RTP: LLQ (strict priority), 20% of link ──────────────
rtr-infrarunbook-core(config-pmap)# class CM-VOICE-RTP
rtr-infrarunbook-core(config-pmap-c)# priority percent 20
rtr-infrarunbook-core(config-pmap-c)# set dscp ef
rtr-infrarunbook-core(config-pmap-c)# exit
! ── VoIP Signalling: CBWFQ 5% ─────────────────────────────────
rtr-infrarunbook-core(config-pmap)# class CM-VOICE-SIG
rtr-infrarunbook-core(config-pmap-c)# bandwidth percent 5
rtr-infrarunbook-core(config-pmap-c)# set dscp cs3
rtr-infrarunbook-core(config-pmap-c)# exit
! ── Business-Critical: CBWFQ 40%, police to 40 Mbps ──────────
rtr-infrarunbook-core(config-pmap)# class CM-BIZ-CRITICAL
rtr-infrarunbook-core(config-pmap-c)# bandwidth percent 40
rtr-infrarunbook-core(config-pmap-c)# set dscp af21
rtr-infrarunbook-core(config-pmap-c)# police rate 40000000 bps burst 1500000
rtr-infrarunbook-core(config-pmap-c-police)# conform-action transmit
rtr-infrarunbook-core(config-pmap-c-police)# exceed-action set-dscp-transmit af22
rtr-infrarunbook-core(config-pmap-c-police)# violate-action drop
rtr-infrarunbook-core(config-pmap-c-police)# exit
rtr-infrarunbook-core(config-pmap-c)# exit
! ── Bulk: CBWFQ 10%, re-mark to CS1 ──────────────────────────
rtr-infrarunbook-core(config-pmap)# class CM-BULK
rtr-infrarunbook-core(config-pmap-c)# bandwidth percent 10
rtr-infrarunbook-core(config-pmap-c)# set dscp cs1
rtr-infrarunbook-core(config-pmap-c)# exit
! ── Default: remainder ────────────────────────────────────────
rtr-infrarunbook-core(config-pmap)# class class-default
rtr-infrarunbook-core(config-pmap-c)# bandwidth percent 25
rtr-infrarunbook-core(config-pmap-c)# set dscp default
rtr-infrarunbook-core(config-pmap-c)# exit
rtr-infrarunbook-core(config-pmap)# exit
Parent Policy-Map: H-QoS Traffic Shaping to WAN Rate
rtr-infrarunbook-core(config)# policy-map PM-PARENT-WAN-EGRESS
rtr-infrarunbook-core(config-pmap)# class class-default
rtr-infrarunbook-core(config-pmap-c)# shape average 100000000
rtr-infrarunbook-core(config-pmap-c)# service-policy PM-CHILD-WAN-EGRESS
rtr-infrarunbook-core(config-pmap-c)# exit
rtr-infrarunbook-core(config-pmap)# exit
The
shape average 100000000(100 Mbps) limits egress to the committed WAN rate, preventing the ISP from dropping packets due to contract violations.
Step 3 — Apply Service-Policies to Interfaces
rtr-infrarunbook-core(config)# interface GigabitEthernet0/0/0
rtr-infrarunbook-core(config-if)# description WAN-TO-ISP-SOLVETHENETWORK
rtr-infrarunbook-core(config-if)# service-policy output PM-PARENT-WAN-EGRESS
rtr-infrarunbook-core(config-if)# exit
For ingress policing (protecting the router from inbound bursts), add an ingress policy on the same interface:
rtr-infrarunbook-core(config)# policy-map PM-WAN-INGRESS-POLICE
rtr-infrarunbook-core(config-pmap)# class class-default
rtr-infrarunbook-core(config-pmap-c)# police rate 100000000 bps burst 3000000
rtr-infrarunbook-core(config-pmap-c-police)# conform-action transmit
rtr-infrarunbook-core(config-pmap-c-police)# exceed-action drop
rtr-infrarunbook-core(config-pmap-c-police)# exit
rtr-infrarunbook-core(config-pmap-c)# exit
rtr-infrarunbook-core(config-pmap)# exit
rtr-infrarunbook-core(config)# interface GigabitEthernet0/0/0
rtr-infrarunbook-core(config-if)# service-policy input PM-WAN-INGRESS-POLICE
rtr-infrarunbook-core(config-if)# exit
Step 4 — Marking at the Distribution Switch (sw-infrarunbook-dist01)
IP phones auto-mark their own RTP traffic as EF. However, PC data traffic arriving on the same access port must be re-marked at the switch before it reaches the router. The Catalyst 9300 supports MQC-based marking on access and trunk ports.
sw-infrarunbook-dist01(config)# class-map match-any CM-PC-DATA
sw-infrarunbook-dist01(config-cmap)# match vlan 30
sw-infrarunbook-dist01(config-cmap)# exit
sw-infrarunbook-dist01(config)# policy-map PM-INGRESS-TRUST
sw-infrarunbook-dist01(config-pmap)# class CM-PC-DATA
sw-infrarunbook-dist01(config-pmap-c)# set dscp default
sw-infrarunbook-dist01(config-pmap-c)# exit
sw-infrarunbook-dist01(config-pmap)# class class-default
sw-infrarunbook-dist01(config-pmap-c)# set dscp default
sw-infrarunbook-dist01(config-pmap-c)# exit
sw-infrarunbook-dist01(config-pmap)# exit
! Apply to uplink toward rtr-infrarunbook-core
sw-infrarunbook-dist01(config)# interface GigabitEthernet1/0/49
sw-infrarunbook-dist01(config-if)# description UPLINK-TO-RTR-INFRARUNBOOK-CORE
sw-infrarunbook-dist01(config-if)# service-policy input PM-INGRESS-TRUST
sw-infrarunbook-dist01(config-if)# exit
Best practice: Never trust DSCP markings from PC endpoints — always re-mark at the first trusted device (distribution switch or router). Trust markings only from authenticated IP phones (via CDP device classification onmls qos trust dscporswitchport voice vlan).
Step 5 — Policing vs Shaping: When to Use Each
Policing measures traffic against a token bucket. Conforming traffic is transmitted (or re-marked); exceeding traffic is dropped immediately. This creates a hard rate limit with potential packet loss — acceptable for bulk or scavenger traffic but never for voice.
Shaping delays excess traffic in a queue (smoothing bursts) rather than dropping it. It consumes memory (the shape queue) and adds delay, making it unsuitable for EF/LLQ classes. Use shaping at the parent policy to match the WAN CIR.
The token bucket parameters:
- CIR (Committed Information Rate) — the average allowed rate in bps
- Bc (Committed Burst) — bytes that can be sent in one interval, = CIR × Tc
- Be (Excess Burst, shaping only) — additional bytes that may be sent after idle periods
! Policing example: 10 Mbps CIR, 1.25 MB Bc
rtr-infrarunbook-core(config-pmap-c)# police rate 10000000 bps burst 1250000
rtr-infrarunbook-core(config-pmap-c-police)# conform-action transmit
rtr-infrarunbook-core(config-pmap-c-police)# exceed-action drop
rtr-infrarunbook-core(config-pmap-c-police)# exit
! Shaping example: 50 Mbps CIR, 6.25 MB Bc, 6.25 MB Be
rtr-infrarunbook-core(config-pmap-c)# shape average 50000000 6250000 6250000
Step 6 — Verification and Monitoring
Verify class-map matching
rtr-infrarunbook-core# show class-map
Class Map match-any CM-VOICE-RTP (id 1)
Match: dscp ef (46)
Class Map match-any CM-VOICE-SIG (id 2)
Match: access-group name ACL-VOIP-SIG
Class Map match-any CM-BIZ-CRITICAL (id 3)
Match: access-group name ACL-BIZ-CRITICAL
Match: dscp af21 (18)
Class Map match-any CM-BULK (id 4)
Match: access-group name ACL-BULK
Match: dscp cs1 (8)
Verify policy-map configuration
rtr-infrarunbook-core# show policy-map PM-CHILD-WAN-EGRESS
Policy Map PM-CHILD-WAN-EGRESS
Class CM-VOICE-RTP
Priority: 20% (20000 kbps), burst bytes 500000, b/w exceed drops: 0
set dscp ef
Class CM-VOICE-SIG
Bandwidth: 5% (5000 kbps), Max Threshold 64 packets
set dscp cs3
Class CM-BIZ-CRITICAL
Bandwidth: 40% (40000 kbps), Max Threshold 64 packets
set dscp af21
police:
cir 40000000 bps, bc 1500000 byte
Verify real-time counters on interface
rtr-infrarunbook-core# show policy-map interface GigabitEthernet0/0/0 output
GigabitEthernet0/0/0
Service-policy output: PM-PARENT-WAN-EGRESS
Class-map: class-default (match-any)
packets: 48291742, bytes: 61811830100
shape (average) cir 100000000, bc 4000000, be 4000000
Service-policy : PM-CHILD-WAN-EGRESS
Class-map: CM-VOICE-RTP (match-any)
packets: 2810445, bytes 449671200
Priority: 20000 kbps, burst bytes 500000, b/w exceed drops: 0
Class-map: CM-BIZ-CRITICAL (match-any)
packets: 11203920, bytes 14340729600
police:
cir 40000000 bps, bc 1500000 byte
conformed 10891204 packets; actions: transmit
exceeded 312716 packets; actions: set-dscp-transmit af22
violated 0 packets; actions: drop
Check queue depth and drops
rtr-infrarunbook-core# show queue GigabitEthernet0/0/0
Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0
Queueing strategy: fifo
Output queue: 0/40 (size/max)
rtr-infrarunbook-core# show interfaces GigabitEthernet0/0/0 | include output drops
Output queue: 0/40 (size/drops)
Verify DSCP markings on egress packets
rtr-infrarunbook-core# debug ip packet detail
! Or use IP SLA probes with DSCP marking verification:
rtr-infrarunbook-core(config)# ip sla 1
rtr-infrarunbook-core(config-ip-sla)# udp-jitter 203.0.113.1 50000 source-ip 10.10.0.1 source-port 50001
rtr-infrarunbook-core(config-ip-sla-jitter)# tos 0xB8
rtr-infrarunbook-core(config-ip-sla-jitter)# frequency 60
rtr-infrarunbook-core(config-ip-sla)# exit
rtr-infrarunbook-core(config)# ip sla schedule 1 life forever start-time now
Step 7 — NBAR2-Based Classification (Protocol Discovery)
When ACL-based matching is impractical (e.g., encrypted flows, dynamic ports), use NBAR2 (Network-Based Application Recognition) to classify by application protocol. NBAR2 is available on ISR 4000 and ASR 1000 with the Cisco DNA Advantage license.
rtr-infrarunbook-core(config)# class-map match-any CM-WEBEX
rtr-infrarunbook-core(config-cmap)# match protocol webex-media
rtr-infrarunbook-core(config-cmap)# match protocol cisco-jabber-video
rtr-infrarunbook-core(config-cmap)# exit
rtr-infrarunbook-core(config)# class-map match-any CM-YOUTUBE
rtr-infrarunbook-core(config-cmap)# match protocol youtube
rtr-infrarunbook-core(config-cmap)# exit
! Enable NBAR2 protocol discovery on the interface first:
rtr-infrarunbook-core(config)# interface GigabitEthernet0/0/0
rtr-infrarunbook-core(config-if)# ip nbar protocol-discovery
rtr-infrarunbook-core(config-if)# exit
! Verify:
rtr-infrarunbook-core# show ip nbar protocol-discovery interface GigabitEthernet0/0/0 stats bit-rate
Step 8 — Saving and Maintaining the Configuration
rtr-infrarunbook-core# copy running-config startup-config
Destination filename [startup-config]?
Building configuration...
[OK]
! Archive for rollback (configure archive before making changes):
rtr-infrarunbook-core(config)# archive
rtr-infrarunbook-core(config-archive)# path tftp://10.10.0.200/infrarunbook-core-$t
rtr-infrarunbook-core(config-archive)# maximum 10
rtr-infrarunbook-core(config-archive)# write-memory
rtr-infrarunbook-core(config-archive)# exit
! Rollback to previous:
rtr-infrarunbook-core# configure replace tftp://10.10.0.200/infrarunbook-core-Jan-1-2026
Related Articles
- [Cisco] Cisco IOS-XE Hardening: Complete Run Book for Management Plane, Control Plane, and Service Lockdown
- [Cisco] Cisco HSRP and VRRP Configuration: Complete Run Book for First Hop Redundancy on IOS/IOS-XE
- [Cisco] Cisco EtherChannel Configuration: LACP, PAgP, and Static — Complete Run Book for IOS/IOS-XE
- [Cisco] What Is VLAN and Why It Is Used in Cisco Networks
