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