🏛️ ArchiZeroTrust / CCIE / QoS / 08 — MQC
📶 QoS · 08

MQC — Modular QoS CLI

Le framework qui structure toute la QoS IOS : class-map pour classifier, policy-map pour agir, service-policy pour appliquer. Comprendre MQC, c'est comprendre comment tous les mécanismes QoS s'articulent.

Avant MQC, la QoS Cisco était un patchwork de commandes incompatibles : CAR pour le policing, CBWFQ avec sa propre syntaxe, pas de hiérarchie possible. MQC introduit en IOS 12.1(1)T un langage unifié : on définit une fois ce qu'on classifie, une fois ce qu'on fait, et on applique où on veut. Tout le reste de QoS (policing, shaping, LLQ, WRED…) s'exprime via MQC.
class-map Qui ? match dscp ef match protocol rtp match access-group 101 référence policy-map Quoi faire ? class CM-VOIX priority 128 class CM-VIDEO bandwidth 256 class class-default applique service-policy Où ? interface Gi0/1 output PM-WAN direction : in / out trafic Interface Gi0/1 512k WAN ① Classifier ② Définir les actions ③ Attacher ④ Appliquer
ObjetRôleCommande de créationPortée
class-mapDéfinir un ensemble de trafic à classifierclass-map [match-all|match-any] <nom>Global — réutilisable dans plusieurs policy-maps
policy-mapAssocier des actions à des classespolicy-map <nom>Global — réutilisable sur plusieurs interfaces
service-policyAttacher une policy-map à une interfaceservice-policy {input|output} <nom>Par interface, par direction — une seule policy
! ① Classifier la voix
class-map match-all CM-VOIX
 match dscp ef

! ② Définir l'action
policy-map PM-WAN
 class CM-VOIX
  priority 128
 class class-default
  fair-queue

! ③ Appliquer sur l'interface
interface GigabitEthernet0/1
 service-policy output PM-WAN
Avant MQC (CAR, CBWFQ natif)Avec MQC
Commandes dispersées, syntaxes différentes par mécanismeSyntaxe unique pour tous les mécanismes QoS
Pas de hiérarchie parent/child possibleImbrication policy-map dans policy-map
Réutilisation impossible — config dupliquée par interfaceclass-map et policy-map réutilisables globalement
Difficile de lire/auditer la config QoSStructure lisible, auditable, exportable
match-all (AND) TOUTES les conditions doivent être vraies dscp ef cos 5 MATCH les deux Paquet match uniquement si DSCP EF ET CoS 5 match-any (OR) AU MOINS UNE condition doit être vraie dscp ef cos 5 MATCH Paquet match si DSCP EF OU si CoS 5 (ou les deux)
Commande matchCe qui est examinéExempleRemarque
match dscpDSCP dans l'en-tête IP (6 bits)match dscp ef af41 af21Valeurs nommées ou décimales (46, 34…). Multiple valeurs = OR interne
match ip dscpAlias de match dscp (IPv4 seulement)match ip dscp efÉviter : match dscp fonctionne aussi en IPv6
match cosCoS 802.1p (3 bits, trame Ethernet)match cos 5Valide uniquement sur interfaces trunk/dot1q
match precedenceIP Precedence (3 bits, ancienne QoS)match precedence 5Priorité=5 ≈ DSCP EF. Héritage pré-DiffServ
match access-groupACL standard ou étenduematch access-group 101Très flexible mais coûteux CPU
match protocolApplication NBAR (L7)match protocol http
match protocol rtp audio
Nécessite ip nbar protocol-discovery sur l'interface
match qos-groupQoS group interne (marquage inter-process)match qos-group 1Marqué avec set qos-group dans une autre policy
match mpls experimentalEXP bits MPLS (3 bits)match mpls experimental topmost 5Réseau MPLS PE/P uniquement
match class-mapImbriquer une autre class-mapmatch class-map CM-VOIXPermet des critères composites complexes
match notInverse d'un critèrematch not dscp defaultClasse "tout sauf BE"
class-default capture tout le trafic qui ne correspond à aucune class-map explicite. Elle est toujours présente dans toute policy-map, même si elle n'est pas déclarée. Sans configuration explicite, le trafic dans class-default reçoit WFQ (sur les interfaces série) ou FIFO (sur les interfaces rapides). À toujours configurer explicitement pour éviter les surprises.
! Exemple class-map composite avec plusieurs critères
class-map match-any CM-INTERACTIVE
 match dscp af21 af22 af23         ! Trafic interactif basse latence
 match cos 2                       ! Marquage CoS sur trunk

class-map match-all CM-VOIP-STRICT
 match dscp ef                     ! Doit avoir DSCP EF
 match cos 5                       ! ET CoS 5 (redondant mais utile en audit)

class-map match-any CM-CRITIQUE
 match dscp ef cs5 cs6            ! Voix OU routing OU vidéo
 match class-map CM-INTERACTIVE  ! OU trafic interactif
class CM-X Bande passante bandwidth 256 bandwidth percent 25 bandwidth remaining % Garantit minimum pas de plafond Priorité (LLQ) priority 128 priority percent 25 priority level 1|2 Garantit latence drop si dépassement Contrôle flux shape average 512k police 1000000 police rate percent shape: buffer/retard police: drop/remark Marquage set dscp ef set cos 5 set qos-group 1 Reclassifier avant transmission Queue avancé random-detect queue-limit 64 fair-queue WRED, profondeur de file WFQ
Règle critique : dans une même class d'une policy-map, on ne peut pas combiner shape + priority ou shape + bandwidth. Ces actions s'excluent mutuellement. Pour avoir LLQ sous un shaper, il faut impérativement une hiérarchie parent/child (voir onglet Hiérarchie).
CombinaisonValide ?Solution si non
bandwidth + set✓ Oui
priority + set✓ Oui
police + set (remark)✓ Oui
bandwidth + random-detect✓ Oui
shape + priority✗ NonParent: shape / Child: priority
shape + bandwidth✗ NonParent: shape / Child: bandwidth
priority + bandwidth (même class)✗ NonClasses séparées
shape + police✗ NonPolicing en ingress, shaping en egress
IOS interdit de mettre shape et priority/bandwidth dans la même classe. La solution : une policy-map parent qui contient le shaper, et une policy-map enfant attachée au parent via service-policy. Le parent crée le sas (buffer logique) ; l'enfant gère comment ce sas est vidé (LLQ, CBWFQ).
policy-map PM-PARENT class class-default shape average 512000 service-policy PM-CHILD policy-map PM-CHILD class CM-VOIX priority 128 class CM-VIDEO bandwidth 128 class CM-APPS bandwidth 128 class class-default fair-queue queue-limit 32 ↑ crée le sas 512k buffer logique interface GigabitEthernet0/1 service-policy output PM-PARENT
RègleDétail
Parent : une seule classLa policy parent ne doit avoir que class class-default contenant le shaper. Plusieurs classes dans le parent sont rarement nécessaires.
shape dans le parentshape average <bps> dans class-default du parent. C'est lui qui crée le sas et active le scheduler enfant.
priority dans l'enfant uniquementIOS rejette priority dans le parent si pas de shaper. Le scheduler LLQ n'a de sens que sur un sas.
Profondeur max 3 niveauxIOS supporte parent → child → grandchild. En pratique, 2 niveaux suffisent pour 99% des scénarios.
bandwidth enfant ≤ shape parentLa somme des bandwidth des classes enfant ne peut pas dépasser le CIR du shaper parent.
! Config complète — shape 512k WAN + LLQ voix + CBWFQ vidéo/apps

class-map match-all CM-VOIX
 match dscp ef
class-map match-all CM-VIDEO
 match dscp af41
class-map match-all CM-APPS
 match dscp af21

policy-map PM-CHILD
 class CM-VOIX
  priority 128          ! LLQ — garantie latence
 class CM-VIDEO
  bandwidth 128         ! CBWFQ — garantie débit
 class CM-APPS
  bandwidth 128
 class class-default
  fair-queue
  queue-limit 32

policy-map PM-PARENT
 class class-default
  shape average 512000  ! CIR 512 kbps → crée le sas
  service-policy PM-CHILD ! Attache le scheduler

interface GigabitEthernet0/1
 bandwidth 512          ! Déclare CIR pour calculs %
 service-policy output PM-PARENT
Internet WAN Routeur Gi0/0 (WAN) service-policy in/out LAN interne service-policy input ✓ classify · mark · police ✗ shape · queue service-policy output ✓ classify · mark · police ✓ shape · queue · WRED trafic vers LAN
ActionInputOutputRemarque
classify (class-map)Les deux directions
set dscp / set cosMarquage dans les deux sens
policePolicing ingress très courant (DoS, SLA)
shapeImpossible en input — on ne retarde pas ce qui entre
priority / bandwidthQueuing uniquement en output
random-detect (WRED)Output uniquement
fair-queueOutput uniquement
ContexteCommandeCas d'usage
Interface physiqueinterface Gi0/1 → service-policy output PMLe plus courant — WAN, uplink
Sous-interface dot1qinterface Gi0/1.100 → service-policy output PMQoS par VLAN
Tunnel GRE/IPSecinterface Tunnel0 → service-policy output PMNécessite qos pre-classify sur interface physique pour voir l'IP interne
Virtual-template (PPPoE)virtual-template 1 → service-policy output PMDSL, sessions PPPoE per-subscriber
Dialer (ISDN/async)dialer → service-policy output PMLiens à la demande
Une seule policy par direction. IOS rejette la commande si une policy est déjà appliquée dans la même direction. Pour modifier, retirer d'abord l'ancienne : no service-policy output PM-OLD puis appliquer la nouvelle.
La commande principale pour vérifier que la QoS fonctionne est show policy-map interface <nom>. Elle montre pour chaque classe : les paquets matchés, les actions appliquées, les drops, la profondeur de file. C'est l'outil de diagnostic #1 pour le lab CCIE.
Router# show policy-map interface GigabitEthernet0/1

 GigabitEthernet0/1

  Service-policy output: PM-PARENT
    Class-map: class-default (match-any)
      5248 packets, 6234112 bytes
      5 minute offered rate 1024000 bps, drop rate 0 bps
      Match: any
      Traffic Shaping
           Current Be_sent: 0/512000 (bits/max)
           Bc: 64000 bits, Be: 0 bits  Tc: 125 ms
             ↑ Tc = 125ms, Bc = 64000 bits = 512kbps × 0.125s
           Queue Depth/Total Drops/No-buffer Drops: 0/0/0
           Delayed Pkts: 0

      Service-policy : PM-CHILD
        Class-map: CM-VOIX (match-all)
          342 packets, 48656 bytes
          5 minute offered rate 128000 bps, drop rate 0 bps
          Match: dscp ef (46)
          Queueing
            Strict Priority
            Output Queue: Conversation 24
            Bandwidth 128 (kbps) Burst: 3200 (Bytes)
            (pkts matched/bytes matched) 342/48656
            (total drops/bytes drops): 0/0  ← 0 drop : voix OK

        Class-map: CM-VIDEO (match-all)
          1024 packets, 983040 bytes
          5 minute offered rate 256000 bps, drop rate 18000 bps
          Match: dscp af41 (34)
          Queueing
            Output Queue: Conversation 25
            Bandwidth 128 (kbps) Max Threshold 64 (packets)
            (pkts matched/bytes matched) 1024/983040
            (depth/total drops/no-buffer drops) 64/89/89  ← file PLEINE !
               ↑ bandwidth 128k insuffisant pour 256kbps offert

        Class-map: class-default (match-any)
          3882 packets, 5202456 bytes
          5 minute offered rate 512000 bps, drop rate 0 bps
          Match: any
          Weighted Fair Queueing
            Output Queue: Conversation 0
CompteurSignificationValeur normale
drop rate XbpsDébit de drops actuel en bps0 pour voix/vidéo critique
total drops / bytes dropsDrops cumulatifs depuis application policy0 idéal pour LLQ
depthProfondeur actuelle de la file (paquets)Proche de 0 si bien dimensionné
Queue Depth/Total DropsShaper : paquets en attente dans le sasVarie — normal si > 0
offered rate vs drop rateSi drop rate > 0 : classe sous-dimensionnéedrop rate = 0
Delayed PktsPaquets retardés par le shaperVarie — attendu en shaping
! Voir toutes les class-maps configurées
show class-map

! Voir une policy-map spécifique
show policy-map PM-PARENT

! Voir les policies appliquées sur toutes les interfaces
show policy-map interface

! Réinitialiser les compteurs
clear counters GigabitEthernet0/1

! Debug (attention : très verbeux en prod)
debug qos classify
debug qos match

⚠ class-default toujours présente

Même si tu ne la configures pas, class-default existe dans toute policy-map et capte tout le trafic non classifié. En output sur une interface GigE, sans configuration explicite, elle fait du FIFO — ce qui peut saturer la file et impacter toutes les autres classes. À toujours configurer explicitement avec fair-queue ou bandwidth remaining.

⚠ match-all vs match-any — piège classique du lab

match-all (défaut) = AND : toutes les conditions doivent être vraies. Un paquet DSCP EF sans CoS 5 ne matche PAS class-map match-all CM-X / match dscp ef / match cos 5. Erreur fréquente : utiliser match-all quand on veut "DSCP EF OU CoS 5" — résultat : rien ne matche.

⚠ priority dans un child exige shape dans le parent

Si tu as un service-policy PM-CHILD dans le parent et que PM-CHILD contient priority, IOS exige que le parent ait un shape average dans la même classe. Sans shaper, LLQ n'a aucun sas sur lequel opérer et IOS retourne une erreur à l'application de la policy.

⚠ QoS pre-classify sur tunnel

Sur un tunnel GRE ou IPSec, la policy appliquée sur l'interface physique voit l'en-tête externe (IP tunnel), pas l'IP interne. Pour classifier sur la VoIP interne, il faut qos pre-classify sur l'interface tunnel. Sinon tout le trafic tombe dans class-default et la voix n'est pas priorisée.

⚠ NBAR nécessite ip nbar protocol-discovery

match protocol http ou match protocol rtp ne fonctionnent pas si ip nbar protocol-discovery n'est pas activé sur l'interface. IOS accepte la config sans erreur — mais au runtime, rien ne matche. Toujours vérifier avec show ip nbar protocol-discovery interface.

⚠ Une seule service-policy par direction

IOS n'accepte qu'une seule policy-map par direction sur une interface. Si tu appliques une deuxième policy sans retirer la première, IOS refuse silencieusement ou retourne une erreur. En lab : toujours no service-policy output PM-OLD avant de reconfigurer.

⚠ bandwidth ≠ plafond — c'est un minimum garanti

bandwidth 256 dans une class garantit 256 kbps minimum quand la file est saturée. Mais si les autres classes sont vides, cette classe peut utiliser toute la bande passante disponible. Ce n'est pas un limiteur. Pour limiter : utiliser police.

⚠ sum(bandwidth) dans l'enfant ne peut pas dépasser le CIR parent

Si ton shaper parent est à 512 kbps et que tu configures priority 256 + bandwidth 256 + bandwidth 256 dans l'enfant, IOS rejette la config : 768 kbps > 512 kbps. Règle : la somme de toutes les allocations explicites dans le child doit être ≤ 75% du CIR parent (les 25% restants restent pour class-default).

Quatre exercices pour valider ta compréhension de MQC. Chaque exercice est indépendant — une popup affiche la config IOS complète et les explications après ta réponse.

🎯 Jeu 1 — Construire la class-map

On te donne un flux à classifier. Sélectionne tous les critères match corrects pour construire la class-map. Plusieurs réponses peuvent être correctes.

🔀 Jeu 2 — match-all ou match-any ?

On te montre un paquet avec ses attributs et deux class-maps. Clique sur la class-map que le paquet va matcher (ou "Aucune").

🏗️ Jeu 3 — Assembler la policy-map

On te donne un scénario réseau. Sélectionne dans le bon ordre les blocs de configuration pour construire la policy-map correcte.

🔍 Jeu 4 — Diagnostiquer le show policy-map

On te montre une sortie de show policy-map interface. Identifie le problème.

Clique sur une carte pour révéler la réponse.

Quelle est la différence entre match-all et match-any ?
match-all = AND : toutes les conditions doivent être vraies.
match-any = OR : au moins une condition doit être vraie. Par défaut c'est match-all si non spécifié.
Quelle commande vérifie qu'une class-map matche bien du trafic ?
show policy-map interface <nom> — regarder le champ "packets matched" et "bytes matched" de la classe. Si = 0 longtemps après le trafic, la classification est fausse.
Peut-on avoir shape et priority dans la même classe ?
Non. IOS les interdit dans la même classe. Il faut une hiérarchie : shape average dans la policy parent (class-default), et priority dans la policy enfant attachée via service-policy.
bandwidth 256 dans une classe — ça plafonne le trafic à 256 kbps ?
Non. bandwidth garantit un minimum de 256 kbps quand la file est congestionnée. Si les autres classes sont vides, la classe peut utiliser plus. Pour limiter : utiliser police.
Que se passe-t-il si ip nbar protocol-discovery n'est pas configuré sur l'interface et qu'on utilise match protocol http ?
IOS accepte la config sans erreur mais au runtime, rien ne matche. Tout le trafic HTTP tombe dans class-default. Toujours activer ip nbar protocol-discovery sur l'interface avant d'utiliser NBAR.
Peut-on appliquer deux service-policy output différentes sur la même interface ?
Non. Une seule policy-map par direction. IOS refuse la deuxième. Pour changer : no service-policy output PM-OLD puis appliquer la nouvelle.
Quelle commande est nécessaire pour que match protocol rtp fonctionne ?
ip nbar protocol-discovery sous l'interface. Vérifie avec show ip nbar protocol-discovery interface Gi0/1.
Pourquoi faut-il qos pre-classify sur un tunnel ?
Sans qos pre-classify, la policy sur l'interface physique voit l'en-tête IP externe du tunnel, pas l'IP interne. Les class-maps basées sur le DSCP de l'IP interne ne matchent rien. qos pre-classify permet de classifier avant encapsulation.
Quelle est la profondeur maximale d'imbrication MQC sous IOS ?
3 niveaux : parent → child → grandchild. En pratique 2 niveaux suffisent pour 99% des cas. Au-delà de 3, IOS retourne une erreur à la configuration.
Dans un child policy-map, quelle règle s'applique sur la somme des bandwidth ?
La somme des allocations explicites (bandwidth + priority) dans le child doit être ≤ au CIR du shaper parent. IOS réserve au moins 25% pour class-default. Exemple : CIR 512k → max allouable explicitement ≈ 384k.
!================================================
! 1. CLASS-MAP
!================================================
class-map [match-all | match-any] NOM
 match dscp ef af41 af21 default
 match ip dscp 46                   ! IPv4 uniquement
 match cos 5
 match precedence 5
 match access-group 101
 match protocol http               ! NBAR requis
 match protocol rtp audio
 match qos-group 1
 match mpls experimental topmost 5
 match class-map CM-AUTRE          ! Imbrication
 match not dscp default            ! Inversion

!================================================
! 2. POLICY-MAP — actions disponibles
!================================================
policy-map PM-NOM
 class CM-NOM
  bandwidth 256                    ! kbps — minimum garanti
  bandwidth percent 25             ! % du lien (ref: bandwidth interface)
  bandwidth remaining percent 30   ! % de la BW résiduelle
  priority 128                     ! kbps — LLQ strict
  priority percent 25
  priority level 1                 ! Multi-level LLQ (level 1 = plus prioritaire)
  shape average 512000            ! bps — crée le sas
  shape peak 512000               ! bps — utilise Be (rafale)
  police 1000000                  ! bps
  police rate 1000000 bps burst 10000 byte
  police rate percent 10
  set dscp ef
  set cos 5
  set qos-group 1
  random-detect                    ! WRED par défaut (précédence)
  random-detect dscp-based         ! WRED par DSCP
  queue-limit 64 packets
  fair-queue
  service-policy PM-CHILD        ! Hiérarchie — child attaché ici

!================================================
! 3. SERVICE-POLICY
!================================================
interface GigabitEthernet0/1
 service-policy input  PM-INGRESS
 service-policy output PM-EGRESS
 ip nbar protocol-discovery          ! Requis pour match protocol
 qos pre-classify                    ! Requis sur tunnel pour voir IP interne
 bandwidth 512                        ! Déclare CIR pour calculs % QoS

!================================================
! 4. VÉRIFICATION
!================================================
show class-map
show policy-map
show policy-map PM-NOM
show policy-map interface GigabitEthernet0/1
show ip nbar protocol-discovery interface Gi0/1
clear counters GigabitEthernet0/1