Brad Fleming from Kanren gave me remote access to a lab MX5 router in order to do the Junos section of this port for when I am very grateful!

There are many different needs for H-QoS and may different ways to configure it. I’m going to be going over one particular use case for H-QoS in which I use on a daily basis. More so than any other type of QoS, H-QoS is very hardware specific. Even line-card specific. In this post I’ll be using a Juniper MX5 and a Cisco ME3600X, both which allow me to do H-QoS on their gig ports.

My use case is as follows. Core gig ports are not cheap. ‘Revenue ports’ as ISPs like to call them. Most core kit has a load of gig ports, some 10Gb ports and maybe 40Gb/100Gb ports.

Not all customers want 1 gig link. Some want 10Mb, others 50Mb, some 300Mb. Heck some only want 4Mb. In order not to waste precious revenue ports, these circuits are aggregated into a single physical gig port. i.e. we can put 10 X 100Mb circuits onto a single gig link.

The bigggest problem with doing this is that it gets difficult to give QoS outbound back to the customer unless your hardware can do H-QoS. Let’s take the following port diagram as an example:

port

The physical port is 1Gb. Here I have two customer circuits attached. Customer A is paying for 20Mb while Customer B is paying for 70Mb. Not only do I want to shape their respective queues, I also want to give 30% priority bandwidth to each customer, inside each queue. So I need to shape vlan 2000 to 20Mb, and inside that 20Mb ensure 30% is given to EF packets.

IOS

In IOS I create the child and parent policies.

policy-map 30_70
 class EF
  priority
  police cir percent 30 conform-action transmit  exceed-action drop
 class class-default
  queue-limit percent 100
!
policy-map 20Mb
 class class-default
  shape average 20000000
   service-policy 30_70
!
policy-map 70Mb
 class class-default
  shape average 70000000
   service-policy 30_70

Each policy can then attach to an EVC outbound on a physical port:

ME3600X#sh run int gi0/1
Building configuration...

Current configuration : 674 bytes
!
interface GigabitEthernet0/1
 switchport trunk allowed vlan none
 switchport mode trunk
 mtu 9800
 service instance 1 ethernet
  description CUSTOMER1
  encapsulation dot1q 2000
  rewrite ingress tag pop 1 symmetric
  service-policy output 20Mb
  bridge-domain 150
 !
 service instance 2 ethernet
  description CUSTOMER2
  encapsulation dot1q 2001
  rewrite ingress tag pop 1 symmetric
  service-policy output 70Mb
  bridge-domain 150
 !
end

Junos

H-QoS on Junos is done using a traffic-control profile. This allows you to shape to a specific rate, attach a scheduler inside that profile, and attach that profile to an interface. First let’s create our schedulers and scheduler-map:

darreno> show configuration class-of-service schedulers
EF {
    transmit-rate {
        percent 30;
        exact;
    }
    priority high;
}
BE {
    transmit-rate {
        remainder;
    }
}

darreno> show configuration class-of-service scheduler-maps
OUTBOUND {
    forwarding-class expedited-forwarding scheduler EF;
    forwarding-class best-effort scheduler BE;
}

Now we create our traffic profiles and attach the above scheduler-map to it;

darreno> show configuration class-of-service traffic-control-profiles
20Mb {
    scheduler-map OUTBOUND;
    shaping-rate 20m;
70Mb {
    scheduler-map OUTBOUND;
    shaping-rate 70m;
}

Attach the profile to the interface under class-of-service:

darreno> show configuration class-of-service interfaces
ge-1/0/0 {
    unit 2000 {
        output-traffic-control-profile 20Mb;
    }
    unit 2001 {
        output-traffic-control-profile 70Mb;
    }
}

Note that you need to configure hierarchical-scheduler under the interface itself:

darreno> show configuration interfaces ge-1/0/0
hierarchical-scheduler;
vlan-tagging;

unit 2000 {
    description "Customer 1";
    vlan-id 2000;
}
unit 2001 {
    description "Customer 2";
    vlan-id 2001;
}

Verification

IOS still has much better verification than Junos. I don’t know why Junos makes it so difficult to view this kind of information. When using service instances in IOS as above, the verification command has changed a bit, somewhat annoyingly.

ME3600X#sh ethernet service instance policy-map
  GigabitEthernet0/1: EFP 1

  Service-policy output: 20Mb

    Class-map: class-default (match-any)
      578 packets, 45186 bytes
      5 minute offered rate 1000 bps, drop rate 0000 bps
      Match: any
  Traffic Shaping
    Average Rate Traffic Shaping
    Shape 20000 (kbps)
      Output Queue:
        Default Queue-limit 49152 bytes
        Tail Packets Drop: 0
        Tail Bytes Drop: 0

      Service-policy : 30_70

        Class-map: EF (match-all)
          0 packets, 0 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match:  dscp ef (46)
          Strict Priority
          police:
            cir percent 30 % bc 250 ms
            cir 6000000 bps, bc 187500 bytes
            conform-action transmit
            exceed-action drop
          conform: 0 (packets) 0 (bytes)
          exceed: 0 (packets) 0 (bytes)
          conform: 0 bps, exceed: 0 bps
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0

        Class-map: class-default (match-any)
          578 packets, 45186 bytes
          5 minute offered rate 1000 bps, drop rate 0000 bps
          Match: any
          Queue-limit 100 percent
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0
  GigabitEthernet0/1: EFP 2

  Service-policy output: 70Mb

    Class-map: class-default (match-any)
      501 packets, 39092 bytes
      5 minute offered rate 2000 bps, drop rate 0000 bps
      Match: any
  Traffic Shaping
    Average Rate Traffic Shaping
    Shape 70000 (kbps)
      Output Queue:
        Default Queue-limit 49152 bytes
        Tail Packets Drop: 0
        Tail Bytes Drop: 0

      Service-policy : 30_70

        Class-map: EF (match-all)
          0 packets, 0 bytes
          5 minute offered rate 0000 bps, drop rate 0000 bps
          Match:  dscp ef (46)
          Strict Priority
          police:
            cir percent 30 % bc 250 ms
            cir 21000000 bps, bc 656250 bytes
            conform-action transmit
            exceed-action drop
          conform: 0 (packets) 0 (bytes)
          exceed: 0 (packets) 0 (bytes)
          conform: 0 bps, exceed: 0 bps
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0

        Class-map: class-default (match-any)
          501 packets, 39092 bytes
          5 minute offered rate 2000 bps, drop rate 0000 bps
          Match: any
          Queue-limit 100 percent
          Queue-limit current-queue-depth 0 bytes
              Output Queue:
                Default Queue-limit 49152 bytes
                Tail Packets Drop: 0
                Tail Bytes Drop: 0