QoS pre-classification

Implementing quality of service provisions on virtual tunnel interfaces (VTIs) poses a challenge: QoS policy enforcement is normally applied only after tunnel encapsulation has taken place. Consider the following service policy applied to a GRE tunnel:

class-map match-all ICMP
 match access-group name MATCH_ICMP
class-map match-all GRE
 match access-group name MATCH_GRE
!
!
policy-map MyPolicy
 class ICMP
 class GRE
!
interface Tunnel0
 ip address 192.168.0.1 255.255.255.252
 tunnel source 10.0.0.1
 tunnel destination 10.0.0.2
!
interface FastEthernet0/0
 ip address 10.0.0.1 255.255.255.252
 service-policy output MyPolicy
!
ip access-list extended MATCH_GRE
 permit gre any any
ip access-list extended MATCH_ICMP
 permit icmp any any

(Note that the policy map used as an example here does not actually enforce any policy; its class maps are included simply to illustrate the manner in which packets are being matched.)

In default operation, our QoS policy will be applied to packets exiting the physical interface only after they have undergone tunnel encapsulation:

default_classification.png

When we generate ICMP traffic to the far end of the tunnel, we can verify that our policy only matches the packets as GRE traffic:

R1# ping 192.168.0.2 repeat 10

Type escape sequence to abort.
Sending 10, 100-byte ICMP Echos to 192.168.0.2, timeout is 2 seconds:
!!!!!!!!!!
Success rate is 100 percent (10/10), round-trip min/avg/max = 8/10/24 ms
R1# show policy-map interface f0/0
 FastEthernet0/0

Service-policy output: MyPolicy

Class-map: ICMP (match-all)
  0 packets, 0 bytes
  30 second offered rate 0 bps
  Match: protocol icmp

Class-map: GRE (match-all)
  10 packets, 1240 bytes
  30 second offered rate 0 bps
  Match: protocol gre

Class-map: class-default (match-any)
  5 packets, 620 bytes
  30 second offered rate 0 bps, drop rate 0 bps
  Match: any 

This hinders our ability to differentiate between packets which have undergone tunnel encapsulation. However, enabling QoS pre-classification configures the tunnel interface to maintain a copy of the original packet in memory long enough for the physical interface policy to inspect it.

pre-classification.png

After enabling pre-classification, our policy is applied to the original "inner" header instead of the encapsulation header:

R1# conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)# interface tunnel0
R1(config-if)# qos pre-classify
R1(config-if)# ^Z
R1# clear counters f0/0
Clear "show interface" counters on this interface [confirm]
R1# ping 192.168.0.2 repeat 10

Type escape sequence to abort.
Sending 10, 100-byte ICMP Echos to 192.168.0.2, timeout is 2 seconds:
!!!!!!!!!!
Success rate is 100 percent (10/10), round-trip min/avg/max = 4/8/12 ms
R1# show policy-map interface f0/0
 FastEthernet0/0

Service-policy output: MyPolicy

Class-map: ICMP (match-all)
  10 packets, 1240 bytes
  30 second offered rate 0 bps
  Match: access-group name MATCH_ICMP

Class-map: GRE (match-all)
  0 packets, 0 bytes
  30 second offered rate 0 bps
  Match: access-group name MATCH_GRE

Class-map: class-default (match-any)
  2 packets, 120 bytes
  30 second offered rate 0 bps, drop rate 0 bps
  Match: any 

A couple side notes from my experiments on IOS 12.4(22)T:

  • I initially wrote the class maps to utilize NBAR (match protocol), but for some reason the ICMP class map didn't appear to take effect, so I switched to extended ACLs. Your mileage may vary.

  • Pre-classification seems to have no effect when applied to a VTI performing native IPsec encapsulation (versus a crypto map). Again, this may be IOS version-specific.

Comments

Great article! I don't think I've ever seen QoS pre-classification presented so clearly and simply. I was never sure I completely understood it after the ONT book.

Gran articulo.. me parece estupendo el apote. Se agradecen los comnocimientos :-)

Hi Jeremy Nice article and good explanation of the pre-classification but with VTIs you could also put the policy-map directly onto the VTI itself, same goes for a GRE Tunnel. No need for a pre-classification in that way. best regards

Michel

It might also be important to ensure everyone understands that "qos pre-classify" only carries the temporary copy of the header on the local router.
Once the traffic has exited the physical interface, the header is discarded. Thanks for the quick write up.

The article is really awesome but still I have a doubt how to implement it in IP VPN cloud where in 90% of the customers use GRE.

If the classification policy matches on the ToS byte (and not by using ACLs like in your example), it is not necessary to use the qos pre-classify command. The ToS byte from the original IP header is copied to the outer header by the tunneling mechanism by default.

Good point made by Jan-Klaas Kesteloot above. I would avoid using QoS pre-classify if at all possible as this "feature" regularly has quite a few bugs - advice I received from Cisco TAC. Try a search in the bug tool for "QoS preclassify". Much safer and more reliable to have the traffic marked already and apply based on the ToS byte that is copied from the original packet into the GRE packet.

Hey Stretch, I know this article is a bit old, but I wanted you to know that it helped me out. I was labbing another bloggers post (really close to this one) on this same subject in preparation for my ONT exam, and ran into some NBAR troubles. I was classifying esp, gre, and icmp, and for some reason gre (when using NBAR) was getting the hits when I had the policy applied to the physical int, and the qos pre-classify applied to the tunnel, when I pinged across. I found your article confirming my suspicions and replaced them with acl's and whoila! Works as designed. Do you think this is an IOS bug or just the way NBAR looks at traffic?

Leave a Comment


Register to comment as a member. You'll look cooler.

Optional; will not be displayed publicly or given out.

Only personal (e.g. blog, Twitter, or LinkedIn) and/or on-topic links, please.