The EXP (Experimental) bits in the MPLS header are used for QoS. The EXP field is 3 bits long, which is the same length as the IPP field. (The IPP field is deprecated but the first three bits of the DSCP value map directly to an IPP value).
When an ingress PE does label imposition, it automatically copies the IP Precedence value in the IP header to the MPLS header EXP value. This is true for both IOS-XE and IOS-XR.
QoS for MPLS is very similar to regular QoS on IP traffic, except you match on the MPLS EXP value instead of DSCP, IPP, CoS, etc.
QoS Group
You should also be aware of the QoS Group feature, which is used to map an EXP value to a QoS Group, which is an internal “tag” put on the packet. This is used on the egress PE in order to apply policy to traffic without needing to classify IP traffic.
The problem that QoS group solves, is that the MPLS label has been popped off already when preforming shaping on the egress interface of the egress PE, so you can’t match the EXP value any longer. The solution is to map the EXP value to a QoS Group on ingress, and then shape the traffic on egress based on the QoS Group. The QoS Group is basically an internal placeholder. It is not a literal marking on the packet itself, but instead an internal marking associated with the packet and held in memory on the router. In the lab below we’ll use the QoS Group feature to solve the problem of shaping on the egress interface on the egress PE.
Lab
We’ll use a regular L3VPN topology, with an extra C router at each site (C1 and C2). Here are the startup configs:
#C1
hostname C1
!
line con 0
logging sync
!
int Gi1
ip address 10.1.1.10 255.255.255.0
no shut
!
router ospf 1
network 10.0.0.0 0.255.255.255 area 0
!
username cisco password cisco
!
enable password cisco
!
line vty 0 4
login local
transport input telnet
#CE1
hostname CE1
!
line con 0
logging sync
!
int Gi1
ip address 10.1.1.1 255.255.255.0
no shut
!
int Gi2
ip address 100.64.0.2 255.255.255.252
no shut
!
router bgp 65000
neighbor 100.64.0.1 remote-as 100
network 10.1.1.0 mask 255.255.255.0
!
router ospf 1
redistribute bgp 65000
network 10.0.0.0 0.255.255.255 area 0
#C2
hostname C2
!
line con 0
logging sync
!
int Gi1
ip address 10.1.2.10 255.255.255.0
no shut
!
router ospf 1
network 10.0.0.0 0.255.255.255 area 0
!
username cisco password cisco
!
enable password cisco
!
line vty 0 4
login local
transport input telnet
#CE2
hostname CE2
!
line con 0
logging sync
!
int Gi1
ip address 10.1.2.1 255.255.255.0
no shut
!
int Gi2
ip address 100.64.0.6 255.255.255.252
no shut
!
router bgp 65001
neighbor 100.64.0.5 remote-as 100
network 10.1.2.0 mask 255.255.255.0
!
router ospf 1
redistribute bgp 65001
network 10.0.0.0 0.255.255.255 area 0
#PE1
hostname PE1
!
line con 0
logging sync
!
vrf definition CUSTOMER
rd 100:1
route-target both 100:1
address-family ipv4 unicast
exit
!
int Gi1
vrf forwarding CUSTOMER
ip address 100.64.0.1 255.255.255.252
no shut
!
int Gi2
ip address 10.1.3.1 255.255.255.0
no shut
ip router isis
isis network point-to-point
mpls ip
!
int lo0
ip address 1.1.1.1 255.255.255.255
ip router isis
!
router isis
net 49.0001.0000.0000.0001.00
is-type level-2-only
!
router bgp 100
neighbor 2.2.2.2 remote-as 100
neighbor 2.2.2.2 update-source lo0
address-family vpnv4
neighbor 2.2.2.2 activate
address-family ipv4 unicast vrf CUSTOMER
neighbor 100.64.0.2 remote-as 65000
#P3
hostname P3
!
line con 0
logging sync
!
int Gi1
ip address 10.1.3.3 255.255.255.0
no shut
ip router isis
isis network point-to-point
mpls ip
!
int Gi2
ip address 10.3.4.3 255.255.255.0
no shut
ip router isis
isis network point-to-point
mpls ip
!
int lo0
ip address 3.3.3.3 255.255.255.255
ip router isis
!
router isis
net 49.0001.0000.0000.0003.00
is-type level-2-only
#P4
hostname P4
!
int Gi0/0/0/1
ip address 10.3.4.4/24
no shut
!
int Gi0/0/0/0
ip address 10.2.4.4/24
no shut
!
int lo0
ip address 4.4.4.4/32
!
router isis 1
net 49.0001.0000.0000.0004.00
is-type level-2-only
interface Gi0/0/0/0
point-to-point
address-family ipv4 unicast
int Gi0/0/0/1
point-to-point
address-family ipv4 unicast
int Lo0
address-family ipv4 unicast
!
mpls ldp
int Gi0/0/0/0
int Gi0/0/0/1
#PE2
hostname PE2
!
vrf CUSTOMER
address-family ipv4 unicast
import route-target 100:1
export route-target 100:1
!
int Gi0/0/0/1
ip address 10.2.4.2/24
no shut
!
int Gi0/0/0/0
vrf CUSTOMER
ip address 100.64.0.5/30
no shut
!
int lo0
ip address 2.2.2.2/32
!
router isis 1
net 49.0001.0000.0000.0002.00
is-type level-2-only
int Gi0/0/0/1
point-to-point
address-family ipv4 unicast
int Lo0
address-family ipv4 unicast
!
router bgp 100
address-family ipv4 unicast
address-family vpnv4 unicast
neighbor 1.1.1.1
remote-as 100
update-source lo0
address-family vpnv4 unicast
vrf CUSTOMER
rd 100:1
address-family ipv4 unicast
neighbor 100.64.0.6
remote-as 65001
address-family ipv4 unicast
route-policy PASS in
route-policy PASS out
!
mpls ldp
int Gi0/0/0/1
!
route-policy PASS
pass
end-policy
If you’ve setup the inital lab correctly, you should be able to telnet from C1 to C2.
The customer has purchased QoS service from the SP. The SLA gaurantees that voice traffic will have 5mb and low latency, while data traffic will have 20mb and no latency gaurantee. The SP tells the customer that the voice traffic must be marked with IPP 5 or DSCP 46 (EF) in order to receive this treatment.
For this lab, we’ll use icmp as a substitute for voice traffic, and telnet as a substitute for general data traffic.
On the C routers, we’ll create an input policy that simply lets us count the IP Precedence markings on received traffic. We’ll use this to validate the markings on received traffic.
#C1, C2
class-map IPP_1
match ip precedence 1
class-map IPP_2
match ip precedence 2
class-map IPP_3
match ip precedence 3
class-map IPP_4
match ip precedence 4
class-map IPP_5
match ip precedence 5
class-map IPP_6
match ip precedence 6
class-map IPP_7
match ip precedence 7
class-map IPP_0
match ip precedence 0
!
policy-map COUNT_IPP
class IPP_0
class IPP_1
class IPP_2
class IPP_3
class IPP_4
class IPP_5
class IPP_6
class IPP_7
!
int Gi1
service-policy input COUNT_IPP
From C1, ping C2 and telnet to C2. Then check the counters on the class maps on the policy-map applied to Gi1.
Telnet automatically uses IP Precedence 6. This is because telnet is considered as network traffic. Network traffic is given the highest preference, IPP 6 and 7. We’ll need to re-mark this on the CEs in order to substitute telnet as voice traffic in our lab.
On CE1 and CE2, create an input service policy which matches IPP 6 and re-marks it as IPP 5.
#CE1, CE2
class-map IPP_6
match ip precedence 6
!
policy-map REMARK_TELNET
class IPP_6
set ip precedence 5
!
int Gi1
service-policy input REMARK_TELNET
Telnet from C1 to C2 again, and this time you should see the IPP_5 counters climb.
If we take a pcap at any point in the SP network, we can see that the IP Precedence is automatically mapped to the EXP field in all MPLS labels. Both the transport and service label reflect the IP Precedence value.
We’ll now configure the SP QoS policy which will reserve bandwidth and minimize delay for voice traffic.
#PE1
class-map VOICE
match mpls experimental topmost 5
!
policy-map VOICE_POLICY
class VOICE
priority 5000
class class-default
bandwidth 20000
!
int Gi2
service-policy output VOICE_POLICY
#P3
class-map VOICE
match mpls experimental topmost 5
!
policy-map VOICE_POLICY
class VOICE
priority 5000
class class-default
bandwidth 20000
!
int range Gi1-2
service-policy output VOICE_POLICY
#P4
class-map VOICE
match mpls experimental topmost 5
!
policy-map VOICE_POLICY
class VOICE
priority level 1
class class-default
bandwidth 20000
!
int Gi0/0/0/0
service-policy output VOICE_POLICY
!
int Gi0/0/0/1
service-policy output VOICE_POLICY
#PE2
class-map VOICE
match mpls experimental topmost 5
!
policy-map VOICE_POLICY
class VOICE
priority level 1
class class-default
bandwidth 20000
!
int Gi0/0/0/1
service-policy output VOICE_POLICY
Initiate telnet traffic between the C routers again. If you check any core routers, you should see the VOICE class counters incrementing. (XRv does not appear to work - it tells me that the service policy is not installed. I believe this is just a limitation of the virtual image. You can apply the policy in the config but it doesn’t actually take effect.)
The problem right now is that we are not applying the policy to the egress interfaces on PE1 and PE2 when they act as the egress PE. The router cannot look up the MPLS EXP field in this case, because the MPLS labels are already gone. Instead of classifying the traffic on egress, we can use the qos-group to classify the traffic on ingress and map it to a qos-group. We can then use the qos-group in the policy that is applied to the egress interface facing the CE.
#PE1
policy-map EXP_TO_QOSGROUP
class VOICE
set qos-group 5
!
class-map QOS_GROUP_5
match qos-group 5
!
policy-map EGRESS_VOICE_POLICY
class QOS_GROUP_5
priority 5000
class class-default
bandwidth 20000
!
int Gi2
service-policy input EXP_TO_QOSGROUP
int Gi1
service-policy output EGRESS_VOICE_POLICY
#PE2
policy-map EXP_TO_QOSGROUP
class VOICE
set qos-group 5
!
class-map QOS_GROUP_5
match qos-group 5
!
policy-map EGRESS_VOICE_POLICY
class QOS_GROUP_5
priority level 1
class class-default
bandwidth 20000
!
int Gi0/0/0/1
service-policy input EXP_TO_QOSGROUP
int Gi0/0/0/0
service-policy output EGRESS_VOICE_POLICY
The commit fails for me on XRv, however we can verify that this policy is working on PE1. Initiate the telnet traffic again and check the counters on both the input policy on Gi2 and output policy on Gi1.
This was a simple lab exercise to get some familiarity with how QoS works in a service provider’s MPLS network. We see that we can only have a maximum of 8 different queues or classes in the MPLS network, as the EXP field is only 3 bits long. By default the IP Precedence value on an IP packet is mapped to the EXP field when MPLS labels are imposed on an IP packet.
We can also use the QoS-Group feature to mark received packets which will have their labels popped off by the time they egress the other interface. This prevents us from having to classify the IP traffic on egress.
As you can see, the QoS tools we use for MPLS on IOS-XE and IOS-XR are extremely similar to QoS in the enterprise world.