QoS Classification and Marking (Part 3)
Classification
As you saw in the previous article, classification is the process of differentiating traffic into separate classes based on some aspect of the traffic. In IOS you use class-maps to define each class of traffic.
Class-maps can match on the following parameters:
Router(config-cmap)#match ?
access-group Access group
any Any packets
application Application to match
cac Call Admission Control
class-map Class map
cos IEEE 802.1Q/ISL class of service/user priority values
destination-address Destination address
discard-class Discard behavior identifier
dscp Match DSCP in IPv4 and IPv6 packets
group-object Match object-group
input-interface Select an input interface to match
ip IP specific values
metadata Metadata to match
mpls Multi Protocol Label Switching specific values
not Negate this match result
packet Layer 3 Packet length
precedence Match Precedence in IPv4 and IPv6 packets
protocol Protocol
qos-group Qos-group
security-group Security group
source-address Source address
traffic-category Match on traffic-category
vlan VLANs to match
'
You will usually match using an ACL or the DSCP value. As you can see, you can even nest class-maps inside each other. To understand why you’d do this, we need to look at the class-map matching options.
By default when you use the command class-map name you create a class-map that matches-all (”match-all”). You can even see this in the running config:
Router(config)#class-map example
Router(config-cmap)#end
Router#show run | sec example
class-map match-all example
The other option is to create a class-map that matches any single match statement, which is called match-any.
class-map match-any example2
match dscp ef
match access-group name ACL1
In the example above, if the packet has an EF marking or it is permitted by ACL1, it matches the class-map. Match-all is a logical and - every match statement must match. Match-any is a logical or - any one match statement in the class-map must match.
You can nest class-maps when you want to do a complex operation such as (X or Y) and Z. The following class-map is an example of this:
ip access-list extended PHONES
permit ip 10.1.1.0 0.0.0.255 any
!
class-map match-any voice_marking
match dscp ef
match ip precedence 5
!
class-map match-all phone_class
match class-map voice_marking
match access-group name PHONES
This class-map named phone_class requires the packet marking to be (EF or IPP 5) and for the ACL named PHONES to permit the traffic. When using ACLs with class-maps, a permit statement is a match statement, and a deny statement is a no-match statement.
We can verify our configured class-maps using the simple show command below:
Router#show class-map
Class Map match-any class-default (id 0)
Match any
Class Map match-all phone_class (id 2)
Match class-map voice_marking
Match access-group name PHONES
Class Map match-any voice_marking (id 1)
Match dscp ef (46)
Match ip precedence 5
The class-map named class-default is always present and available for use in a policy-map. It simply has a match any statement as you can see above.
Marking
As we saw briefly in the previous article, a policy-map is used to take action on traffic matched by a class-map. This includes marking or re-marking traffic. A policy-map must have a class statement. If you want to match all traffic, you simply use the class-default class.
Marking Layer 2 Traffic
The only field you can mark at layer 2 is CoS (Class of Service). The problem with marking at layer 2 is that CoS is only present in an 802.1Q header. Also, the layer 2 header is discarded and created at every layer 3 hop, so the CoS value will not presist through routed hops.

Above is the result after applying the following policy-map:
policy-map cos
class class-default
set cos 5
!
interface GigabitEthernet1
service instance 10 ethernet
encapsulation dot1q 10
service-policy output cos
bridge-domain 10
Generally you won’t use this marking, but it is good to know how it works.
Marking Layer 3 Traffic
DSCP is what you will use most often when marking or re-marking a packet. We have seen basic marking of DSCP and IPP in the previous article. Marking IPP simply marks the most significant three bits of DSCP, since DSCP is backwards compatible with IPP, and IPP has been depreciated.
Below are the options for setting the marking of a packet/frame:
Router(config)#policy-map MARKING
Router(config-pmap)#class class-default
Router(config-pmap-c)#set ?
cos Set IEEE 802.1Q/ISL class of service/user priority
cos-inner Set Inner CoS
discard-class Discard behavior identifier
dscp Set DSCP in IP(v4) and IPv6 packets
ip Set IP specific values
mpls Set MPLS specific values
precedence Set precedence in IP(v4) and IPv6 packets
qos-group Set QoS Group
You can basically ignore set ip because the only options are dscp and precedence which are available without prefixing with ip. (I believe in previous IOS releases, set ip dscp ef would only mark IPv4 packets, and set dscp ef would mark both IPv4 and IPv6 packets. But it seems that set ip dscp marks both IPv4 and IPv6 packets now).
Router(config-pmap-c)#set ip ?
dscp Set DSCP in IP(v4) and IPv6 packets
precedence Set precedence in IP(v4) and IPv6 packets
Re-marking Traffic
Let’s explore how to re-mark traffic. Imagine we operate a service provider network and have an internet customer. We don’t want to allow them to simply set every single packet to EF to get expedited service. We can configure a policy-map that removes any marking on packets received from the customer. This is called a trust boundry - we the service provider do not trust the marking coming from any customer on internet circuits.

In this lab scenario, CE1 is maliciously setting EF on every packet egressing Gi1 by using the following policy-map:
interface GigabitEthernet1
ip address 100.0.1.2 255.255.255.252
ip nat outside
service-policy output SET_EF
!
policy-map SET_EF
class class-default
set dscp ef
When the Customer1 device pings 100.0.0.2, we can see that EF is set and the MPLS experimental bit is set to 5. This is because, by default, the IP Precedence value is mapped to the MPLS label in the Experimental field when an MPLS label is imposed. (We will explore QoS for MPLS in future articles).

We don’t want to allow the customer to mark all traffic like this and hit our priority voice queues in our MPLS core. We can simply re-mark traffic to a value of 0 on the PE.
#R1
policy-map REMOVE-MARKING
class class-default
set dscp default
!
int Gi2
ip address 100.0.1.1 255.255.255.252
service-policy input REMOVE-MARKING
The customer pings 100.0.0.2 again, but this time there is no MPLS Exp value nor DSCP value in the packet:

Policy-map order of operations
Policy-maps work like route-maps in the sense that once a match happens, any further processing stops.
For example, consider this configuration:
ip access-list extended MY-SUBNET
permit ip 10.0.0.0 0.0.0.255 any
!
ip access-list extended RFC1918
permit ip 10.0.0.0 0.255.255.255 any
permit ip 172.0.0.0 0.15.255.255 any
permit ip 192.168.0.0 0.0.255.255 any
!
class-map MY-SUBNET
match access-group name MY-SUBNET
!
class-map RFC1918
match access-group name RFC1918
!
policy-map SET-COS
class RFC1918
set cos 1
class MY-SUBNET
set cos 5
The class MY-SUBNET statement on the policy-map can never receive a hit. This is because the class RFC1918 statement is first, and any 10.0.0.0/24 packet would also match the RFC1918 access-list. So traffic sourced from 10.0.0.0/24 would receive a CoS value of 1, not 5. Processing stops after the first matching class statement.
It’s important to note that the class-default class is always placed at the bottom. For example, with the following configuration, even though you configure class-default first, the router will place it at the very bottom of the policy-map statements:
Router(config)#policy-map SET-COS-NEW
Router(config-pmap)# class class-default
Router(config-pmap-c)# set cos 1
Router(config-pmap-c)# class MY-SUBNET
Router(config-pmap-c)# set cos 5
Router(config-pmap-c)#end
Router#show policy-map SET-COS-NEW
Policy Map SET-COS-NEW
Class MY-SUBNET
set cos 5
Class class-default ! Class-default is always placed at the bottom
set cos 1
Design Choices
In general you should mark packets as close to the ingress edge as possible. This will allow you to use class-maps that simply match the DSCP value on any routers past the marking point.
You should also re-mark traffic at an untrusted boundry, just like we re-marked traffic to the DSCP default for our internet customer.
So what markings should you use?
Cisco recommends the following markings for each class of traffic:
Traffic Class
CoS
IP Precedence
DSCP
Voice payload
5
5
EF
Video payload
4
4
AF41
Voice/Video signaling
3
3
CS3
Critical data
3
3
AF31, AF32, AF33
Transactional data
2
2
AF21, AF22, AF23
Bulk data
1
1
AF11, AF12, AF13
BE (Best effort)
0
0
BE (0)
Scavenger (worse than BE)
0
0
2, 4, 6
Further Reading
Cisco QoS Exam Guide, Wendell Odom and Michael Vacanaugh, Ch. 3 and Ch. 4
Last updated