This post is the second post in a three part series on QoS. If you haven’t read the first blog post, I highly recommend reading the first part here. https://internetwork.blog/2024/09/26/quality-of-service-when-to-use-it/
So I just completed a Quality of Service, or QoS, assessment for a customer. While I was writing the assessment I decided to brush up on my knowledge of QoS best practice to better serve the customer. While it’s still fresh in my brain I figure I would explain QoS here and hopefully someone will get a better understanding from this.
Before we dive into the how, lets talk about the why; why do we need quality of service? QoS is a general term referring to a system that classifies traffic, then based on the classification applies a shaping and policing policy to it. The point is to make sure that when there is congestion on the network that important or time sensitive traffic is prioritized before other non-important or time insensitive traffic. The classic example of this is real-time traffic such as voice and video traffic should get priority over email traffic. Voice traffic cannot handle delays or dropped packets the same way email can, if it takes a second or two more for the email traffic to get to the exchange server the end user would never know, while on the other hand its very noticeable when voice and video traffic is delayed as stutters and freezing occurs in real time.
When thinking about QoS I find it easier to break it up into two categories; Classification, and Policy shaping / Policing. Now I could dive into every scenario and really explain the details around QoS, however to keep this blog post from turning into a literal book (no really there are literal books written on this single subject.) I’m going to keep it high level. Check out these two resources if you want a deep dive into the world of QoS:
- End-to-End QoS Network Design: Quality of Service for Rich-Media & Cloud Networks, 2nd Edition
- Cisco EasyQoS Solution Design Guide (Chapters 1-3,9)
In this post I will focus on a very common deployment of QoS; support of end to end voice and video deployments. Additionally, I will focus on Cisco’s newer MQC way of deploying QoS rather than the older MLS QoS, however we will talk about some differences between MQC and MLS QoS.
QoS Classification
Before traffic can be queued, shaped, and policed it must be sorted into different classes. Classification is the first step to providing priority between different types of data. In a quick overview of the QoS standards (RFC 4594), there are two modern ways you will denote different classes, Class of Service (CoS) which is a layer 2 classification, and Differentiated Services Code Point (DSCP) which is a layer 3 classification. In both cases these classifications are a manipulation of the ToS bits in the packet or frame header depending on if the header is at layer 2 or 3. Think of CoS and DSCP as being two ways to display the same information but at different levels.
Most modern voice and video applications mark their traffic with DSCP markings before sending it to the network card. Because I’m constraining this blog to end to end voice and video traffic we will mostly talk about DSCP and leave CoS to another blog.
To simplify the understanding of the QoS standards Cisco has created a list of recommendations. (Being a network engineer at a Cisco Gold Partner I tend to use Cisco’s recommendations.) It should be noted that these guidelines are not standards; as such, modifications can be made to these recommendations as specific needs or constraints require. Note that the Per-Hop Behavior is using the DSCP class of markings.

We will be referring to this chart a lot in this blog post as it not only has what the different types of applications should be classified as, but also the different queues those classifications should use. We will talk about queues in the next blog post.
Marking and Trusts
Now that we all have a better understanding of DSCP and the priority structure, lets use it. As I said earlier, classification is the first step to providing priority between different types of data. As I said in the previous post, it is important to map out the traffic flows to determine what devices need to be configured for QoS. To expand on this idea, the traffic flow also determines where to mark and trust the traffic. Typically for end-to-end QoS traffic we want to Mark traffic as close to the source and trust on connections between the devices along the path. The Marking configuration is placed on the access switchports that clients are connected to, or if the client is QoS aware, the client will mark its traffic with the right DSCP values. (In which case the access ports can be configured to trust the markings.)
So how do we classify the traffic? Well the first way we classify traffic is to identify the applications traffic, using ACLs or though protocol matching. In both cases we use a policy-map to match either the ACL or protocol, then call a class-map to set the DSCP value. Then once the policy-map is in place we need to call it on each interface that we expect that traffic to be on. This method is considered marking.
Marking Traffic
So lets configured QOS Markings using a template I like to use. To mark traffic with QoS markings you will need three items, the first is an ACL to identify the traffic that needs marking, the second is a class-map to map the ACL and other metrics to a class, last a policy-map to then mark the DSCP value based on the class. Lets start with the ACL:
ip access-list extended QOS_BROADCAST-VIDEO
remark DSCP CS5
permit ip any object-group QOS_BROADCAST-VIDEO_LIST
ip access-list extended QOS_BULKDATA-HIGHDROP
remark DSCP AF13
permit ip any object-group QOS_BULKDATA-HIGHDROP_LIST
ip access-list extended QOS_BULKDATA-LOWDROP
remark DSCP AF11
permit ip any object-group QOS_BULKDATA-LOWDROP_LIST
ip access-list extended QOS_BULKDATA-MEDDROP
remark DSCP AF12
permit ip any object-group QOS_BULKDATA-MEDDROP_LIST
ip access-list extended QOS_DEFAULT
remark DSCP DF
permit ip any object-group QOS_DEFAULT_LIST
ip access-list extended QOS_MANAGEMENT
remark DSCP CS2
permit ip any object-group QOS_MANAGEMENT_LIST
ip access-list extended QOS_MULTIMEDIA-CONFERENCING-HIGHDROP
remark DSCP AF43
permit ip any object-group QOS_MULTIMEDIA-CONFERENCING-HIGHDROP_LIST
ip access-list extended QOS_MULTIMEDIA-CONFERENCING-LOWDROP
remark DSCP AF41
permit ip any object-group QOS_MULTIMEDIA-CONFERENCING-LOWDROP_LIST
ip access-list extended QOS_MULTIMEDIA-CONFERENCING-MEDDROP
remark DSCP AF42
permit ip any object-group QOS_MULTIMEDIA-CONFERENCING-MEDDROP_LIST
ip access-list extended QOS_MULTIMEDIA-STREAMING-HIGHDROP
remark DSCP AF33
permit ip any object-group QOS_MULTIMEDIA-STREAMING-HIGHDROP_LIST
ip access-list extended QOS_MULTIMEDIA-STREAMING-LOWDROP
remark DSCP AF31
permit ip any object-group QOS_MULTIMEDIA-STREAMING-LOWDROP_LIST
ip access-list extended QOS_MULTIMEDIA-STREAMING-MEDDROP
remark DSCP AF32
permit ip any object-group QOS_MULTIMEDIA-STREAMING-MEDDROP_LIST
ip access-list extended QOS_NETWORK-CONTROL
remark DSCP CS6
permit ip any object-group QOS_NETWORK-CONTROL_LIST
ip access-list extended QOS_NETWORK-CS7
remark DSCP CS7
permit ip any object-group QOS_NETWORK-CS7_LIST
ip access-list extended QOS_REALTIME-INTERACTIVE
remark DSCP CS4
permit ip any object-group QOS_REALTIME-INTERACTIVE_LIST
ip access-list extended QOS_SCAVENGER
remark DSCP CS1
permit ip any object-group QOS_SCAVENGER_LIST
ip access-list extended QOS_SIGNALING
remark DSCP CS3
permit ip any object-group QOS_SIGNALING_LIST
ip access-list extended QOS_TRANSACTIONAL-HIGHDROP
remark DSCP AF23
permit ip any object-group QOS_TRANSACTIONAL-HIGHDROP_LIST
ip access-list extended QOS_TRANSACTIONAL-LOWDROP
remark DSCP AF21
permit ip any object-group QOS_TRANSACTIONAL-LOWDROP_LIST
ip access-list extended QOS_TRANSACTIONAL-MEDDROP
remark DSCP AF22
permit ip any object-group QOS_TRANSACTIONAL-MEDDROP_LIST
ip access-list extended QOS_VOICE
remark DSCP EF
permit ip any object-group QOS_VOICE_LIST
As you can see I created an ACL for each of the classes that we will use, making sure to add a remark line so we know what that traffic will eventually be marked as. If you notice the name of the ACL matches the description in the QOS table we looked at in the QOS Classification section. I would then create an object-group listing all of the destination addresses that should be marked. (these are the object-groups that end in _LIST in the template above).
NOTE that if there are ACLs that we don’t use, then there is no need to add them or the class-maps as they will never be used. So now that we have the ACLs completed lets move onto the class-maps:
class-map match-any QOS_NETWORK-CS7_CLASS
description Mark Traffic CS7
match access-group name QOS_NETWORK-CS7
class-map match-any QOS_NETWORK-CONTROL_CLASS
description Mark Traffic CS6
match access-group name QOS_NETWORK-CONTROL
class-map match-any QOS_BROADCAST-VIDEO_CLASS
description Mark Traffic CS5
match access-group name QOS_BROADCAST-VIDEO
class-map match-any QOS_VOICE_CLASS
description Mark Traffic EF
match access-group name QOS_VOICE
class-map match-any QOS_REALTIME-INTERACTIVE_CLASS
description Mark Traffic CS4
match access-group name QOS_REALTIME-INTERACTIVE
class-map match-any QOS_MULTIMEDIA-CONFERENCING-LOWDROP_CLASS
description Mark Traffic AF41
match access-group name QOS_MULTIMEDIA-CONFERENCING-LOWDROP
class-map match-any QOS_MULTIMEDIA-CONFERENCING-MEDDROP_CLASS
description Mark Traffic AF42
match access-group name QOS_MULTIMEDIA-CONFERENCING-MEDDROP
class-map match-any QOS_MULTIMEDIA-CONFERENCING-HIGHDROP_CLASS
description Mark Traffic AF43
match access-group name QOS_MULTIMEDIA-CONFERENCING-HIGHDROP
class-map match-any QOS_SIGNALING_CLASS
description Mark Traffic CS3
match access-group name QOS_SIGNALING
class-map match-any QOS_MULTIMEDIA-STREAMING-LOWDROP_CLASS
description Mark Traffic AF31
match access-group name QOS_MULTIMEDIA-STREAMING-LOWDROP
class-map match-any QOS_MULTIMEDIA-STREAMING-MIDDROP_CLASS
description Mark Traffic AF32
match access-group name QOS_MULTIMEDIA-STREAMING-MIDDROP
class-map match-any QOS_MULTIMEDIA-STREAMING-HIGHDROP_CLASS
description Mark Traffic AF33
match access-group name QOS_MULTIMEDIA-STREAMING-HIGHDROP
class-map match-any QOS_MANAGEMENT_CLASS
description Mark Traffic CS2
match access-group name QOS_MANAGEMENT
match protocol ssh
match protocol snmp
match protocol netflow
class-map match-any QOS_TRANSACTIONAL-LOWDROP_CLASS
description Mark Traffic AF21
match access-group name QOS_TRANSACTIONAL-LOWDROP
class-map match-any QOS_TRANSACTIONAL-MEDDROP_CLASS
description Mark Traffic AF22
match access-group name QOS_TRANSACTIONAL-MEDDROP
class-map match-any QOS_TRANSACTIONAL-HIGHDROP_CLASS
description Mark Traffic AF23
match access-group name QOS_TRANSACTIONAL-HIGHDROP
class-map match-any QOS_SCAVENGER_CLASS
description Mark Traffic CS1
match access-group name QOS_SCAVENGER
class-map match-any QOS_BULKDATA-LOWDROP_CLASS
description Mark Traffic AF11
match access-group name QOS_BULKDATA-LOWDROP
class-map match-any QOS_BULKDATA-MEDDROP_CLASS
description Mark Traffic AF12
match access-group name QOS_BULKDATA-MEDDROP
class-map match-any QOS_BULKDATA-HIGHDROP_CLASS
description Mark Traffic AF13
match access-group name QOS_BULKDATA-HIGHDROP
class-map match-any QOS_DEFAULT
description Mark Traffic Default
match access-group name QOS_DEFAULT
Class-maps can match on multiple items and because of this come with two different behaviors:
- Match-any: Any traffic that matches at least one of the match statements will match the class.
- Match-all: Any traffic that matches all of the match statements will match the class, if one match statement isn’t met then the traffic wont match the class.
For simple markings with a single match statement either works simply because there is only one match statement to match to. In our example above you can see most of the class-maps only match on the ACL. But if you look at the QOS_MANAGEMENT_CLASS you can see there are multiple match statements, matching not only the ACL but different protocols as well. In this case the Match-any behavior is required sense a single flow of traffic can’t match being ssh, snmp, and netflow traffic all at the same time.
Again, if there are classes that won’t be used in your QoS policy then there is no need to add a class-map for that class. Now lets bring it home by looking at the policy-map:
policy-map QOS-CLASSIFY-INPUT-POLICY
class QOS_NETWORK-CS7_CLASS
set dscp cs7
class QOS_NETWORK-CONTROL_CLASS
set dscp cs6
class QOS_BROADCAST-VIDEO_CLASS
set dscp cs5
class QOS_VOICE_CLASS
set dscp ef
class QOS_REALTIME-INTERACTIVE_CLASS
set dscp cs4
class QOS_MULTIMEDIA-CONFERENCING-LOWDROP_CLASS
set dscp af41
class QOS_MULTIMEDIA-CONFERENCING-MEDDROP_CLASS
set dscp af42
class QOS_MULTIMEDIA-CONFERENCING-HIGHDROP_CLASS
set dscp af43
class QOS_SIGNALING_CLASS
set dscp cs3
class QOS_MULTIMEDIA-STREAMING-LOWDROP_CLASS
set dscp af31
class QOS_MULTIMEDIA-STREAMING-MIDDROP_CLASS
set dscp af32
class QOS_MULTIMEDIA-STREAMING-HIGHDROP_CLASS
set dscp af33
class QOS_MANAGEMENT_CLASS
set dscp cs2
class QOS_TRANSACTIONAL-LOWDROP_CLASS
set dscp af21
class QOS_TRANSACTIONAL-MEDDROP_CLASS
set dscp af22
class QOS_TRANSACTIONAL-HIGHDROP_CLASS
set dscp af23
class QOS_SCAVENGER_CLASS
set dscp cs1
class QOS_BULKDATA-LOWDROP_CLASS
set dscp af11
class QOS_BULKDATA-MEDDROP_CLASS
set dscp af12
class QOS_BULKDATA-HIGHDROP_CLASS
set dscp af13
class QOS_DEFAULT
set dscp default
As you can see above, the single policy-map references all of the class-maps we created above, it then sets the DSCP value to the correct value based on class. To enable this policy you would add “service-policy input QOS-CLASSIFY-INPUT-POLICY” to each interface that we want to mark the traffic. Because each switchport can have only one service-policy configured in each direction, if there is already an input service-policy on the switchport then you would need to modify the existing service-policy and add the classes that set the DSCP values.
Trusting Traffic
The second way we classify traffic is to simply let the application tell us what DSCP markings to use. QoS aware applications will mark their traffic with a DSCP value and all we need to do is trust that value once the traffic arrives at our switch. Going back to our constraint of voice and video, this is the method we would use as voice and video applications are QoS aware. Which brings me to the next issue; not all switches behave the same way when it comes to trusting QoS markings.
Remember when I said we will talk about the differences between MQC and MLS QoS? Well now is the time to talk about it. In Cisco’s world the older switches that have the IOS firmware use the MLS method of QoS, while the newer IOS-XE switches use MQC. Cisco created an article that compare the operation of each type, go ahead and check it out here for more details but for our sake we will focus on two items from this list; QoS default, and Trust Configuration.
| Switch Type | IOS | IOS-XE |
| Basic Structure | MLS | MQC |
| QoS default | Disabled | Enabled |
| Port trust default | Disabled | Enabled |
| Trust Configuration | Must be applied to preserve Layer 2 and Layer 3 QoS marking | All packets are trusted (Layer 2 and Layer 3 QoS marking is preserved) by default, unless changed with an application of a specific policy map on the ingress or egress interface |
By default MLS QoS is disabled on all IOS switches. The default behavior then would be to pass traffic and not modify any markings. This works great in our case because the voice and video traffic is already marked, however if there were any bottlenecks leaving the uplinks of the switch then queuing will be done because QoS isn’t enabled. Once enabled then all ports automatically drop any DSCP and CoS values that are marked. To trust those markings we need to explicitly configure each switchport to trust DSCP and/or CoS values. The most common way of doing so is to use the auto qos command set. By enabling mls qos, then using the auto qos trust command on any interface a script is ran that configures class and policy maps, creates table maps for CoS to DSCP mapping, and sets that interface to use those policy maps and table maps. Generally using auto qos makes short work on setting up QoS for voice and video traffic, for more info on the whole auto qos command set click here.
By contrast MQC is enabled on all IOS-XE by default. Additionally, all ports default to a trusted state. This means that out of the box, all newer Cisco switches come ready to handle basic QoS operations. Obviously if you need to modify or expand those QoS settings to include more than just standard voice and video traffic then you will need to configure MQC. Here is a configuration guide for auto qos in MQC if you would like more details.
I think at this point I will stop here, this post is getting long enough and I decided to split my original idea up into a three part series. I told you I didn’t want this to turn into a book. Look out for my next post that will cover the next steps after classification; Queuing and Policing.
