Saturday, February 22, 2020

Traffic Shaping on Cisco IOS

In a previous lesson I explained how we can use shaping to enforce lower bitrates. In this lesson, I will explain how to configure shaping. This is the topology we will use:
iperf client server shaping example
Above we have two routers connected to each other with a serial and FastEthernet link. We’ll use both interfaces to play with shaping. The computers are used for iPerf which is a great application to test the maximum achievable bandwidth. The computer on the left side is our client, on the right side we have the server. Right now we are using the serial interfaces thanks to the following static routes:
R1#
ip route 192.168.2.0 255.255.255.0 192.168.12.2
R2#
ip route 192.168.1.0 255.255.255.0 192.168.12.1
Let’s take a look at some examples!

Configuration



We will start with some low bandwidth settings. Let’s set the clock rate of the serial interface to 128 Kbps:
R2(config)#interface Serial 0/0/0
R2(config-if)#clock rate 128000
Let’s start iPerf on the server:
SERVER# iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
That’s all we have to do on the server side, it will listen on the default port with a window size of 85.3 Kbyte. Here’s what we will do on the client side:
CLIENT# iperf -c 192.168.2.2 -P 8
------------------------------------------------------------
Client connecting to 192.168.2.2, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[  4] local 192.168.1.1 port 44344 connected with 192.168.2.2 port 5001
[  5] local 192.168.1.1 port 44345 connected with 192.168.2.2 port 5001
[  6] local 192.168.1.1 port 44346 connected with 192.168.2.2 port 5001
[  7] local 192.168.1.1 port 44347 connected with 192.168.2.2 port 5001
[  8] local 192.168.1.1 port 44348 connected with 192.168.2.2 port 5001
[  3] local 192.168.1.1 port 44343 connected with 192.168.2.2 port 5001
[  9] local 192.168.1.1 port 44349 connected with 192.168.2.2 port 5001
[ 10] local 192.168.1.1 port 44350 connected with 192.168.2.2 port 5001
The “-P” parameter tells the client to establish eight connections. I’m using multiple connections so we get a nice average bandwidth. Here’s what you will see on the server:
Server#
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-136.2 sec   256 KBytes  15.4 Kbits/sec
[ 10]  0.0-137.0 sec   256 KBytes  15.3 Kbits/sec
[ 11]  0.0-138.0 sec   256 KBytes  15.2 Kbits/sec
[  9]  0.0-138.4 sec   256 KBytes  15.1 Kbits/sec
[  5]  0.0-148.0 sec   384 KBytes  21.3 Kbits/sec
[  6]  0.0-166.7 sec   384 KBytes  18.9 Kbits/sec
[  8]  0.0-171.4 sec   384 KBytes  18.4 Kbits/sec
[  7]  0.0-172.9 sec   384 KBytes  18.2 Kbits/sec
[SUM]  0.0-172.9 sec  2.50 MBytes   121 Kbits/sec
Above you see the individual connections and the [SUM] is the combined throughput of all connections. 121 Kbps comes pretty close to the clock rate of 128 Kbps which we configured.
Let’s configure shaping to limit the throughput of Iperf. This is done with the MQC (Modular Quality of Service) framework which makes the configuration very simple. First we need to configure an access-list which matches our traffic:
R1(config)#ip access-list extended IPERF_CLIENT_SERVER
R1(config-ext-nacl)#permit ip host 192.168.1.1 host 192.168.2.2
The access-list above will match all traffic from 192.168.1.1 to 192.168.2.2. Now we need to create a class-map:
R1(config)#class-map IPERF
R1(config-cmap)#match access-group name IPERF_CLIENT_SERVER
The class map is called IPERF and matches our access-list. Now we can configure a policy-map:
R1(config)#policy-map SHAPE_AVERAGE
R1(config-pmap)#class IPERF
R1(config-pmap-c)#shape ?       
  adaptive        Enable Traffic Shaping adaptation to BECN
  average         configure token bucket: CIR (bps) [Bc (bits) [Be (bits)]],
                  send out Bc only per interval
  fecn-adapt      Enable Traffic Shaping reflection of FECN as BECN
  fr-voice-adapt  Enable rate adjustment depending on voice presence
  peak            configure token bucket: CIR (bps) [Bc (bits) [Be (bits)]],
                  send out Bc+Be per interval
In the policy-map we select the class-map, above you can see the options for shaping. We’ll start with a simple example:
R1(config-pmap-c)#shape average ?
  <8000-154400000>  Target Bit Rate (bits/sec). (postfix k, m, g optional;
                    decimal point allowed)
  percent           % of interface bandwidth for Committed information rate
We will go for shape average where we have to specify the target bit rate. Let’s go for 64 Kbps (64000 bps):
R1(config-pmap-c)#shape average 64000 ?
  <32-154400000>  bits per interval, sustained. Recommend not to configure, the
                  algorithm will fi
When you configure the target bit rate, there’s an option to specify the bits per interval. Cisco IOS recommends you not to configure this manually so for now, we’ll stick to configuring the bit rate. This means Cisco IOS will automatically calculate the Bc and Tc:
R1(config-pmap-c)#shape average 64000
That’s all there is to it. Now we can activate our policy-map on the interface:
R1(config)#interface Serial 0/0/0
R1(config-if)#service-policy output SHAPE_AVERAGE
Everything is now in place, let’s try iPerf again:
CLIENT# iperf -c 192.168.2.2 -P 8
Here’s the sum on the server:
SERVER#
[SUM]  0.0-300.5 sec  2.12 MBytes  59.3 Kbits/sec
Great, that’s close to 64 Kbps. Here’s what it looks like on our router:
R1#show policy-map interface Serial 0/0/0
 Serial0/0/0 

  Service-policy output: SHAPE_AVERAGE

    Class-map: IPERF (match-all)
      1916 packets, 2815928 bytes
      5 minute offered rate 41000 bps, drop rate 0 bps
      Match: access-group name IPERF_CLIENT_SERVER
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/324/0
      (pkts output/bytes output) 1592/2330664
      shape (average) cir 64000, bc 256, be 256
      target shape rate 64000

    Class-map: class-default (match-any)
      102 packets, 7456 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: any 
      
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/0/0
      (pkts output/bytes output) 47/3319
Above you can see that we have matched packets on our policy-map. Cisco IOS decided to use 256 bits for the Bc value.
The example above is of a Cisco 2800 router running IOS 15.1 which only shows you the calculated Bc value. Older Cisco IOS versions show a lot more detailed information, including the calculated Tc value.
How did it come up with this value? The Tc can be calculated like this:
Tc = Bc / CIR
This is what the formula looks like:
256 / 64000 = 0.004.
By using a Bc value of 256 bits, our Tc becomes 4 ms.
Let’s look at some more examples, I’ll also explain how to change the Be and Tc values.
Let’s set the clock rate to 256 Kbps and shape to 128 Kbps:
R2(config)#interface Serial 0/0/0
R2(config-if)#clock rate 256000
Now we only have to change our shaping configuration:
R1(config)#policy-map SHAPE_AVERAGE
R1(config-pmap)#class IPERF
R1(config-pmap-c)#shape average 128000
Here’s what it looks like on the router:
R1#show policy-map interface Serial 0/0/0
 Serial0/0/0 

  Service-policy output: SHAPE_AVERAGE

    Class-map: IPERF (match-all)
      1916 packets, 2815928 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: access-group name IPERF_CLIENT_SERVER
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/324/0
      (pkts output/bytes output) 1592/2330664
      shape (average) cir 128000, bc 512, be 512
      target shape rate 128000
This time we have a Bc of 512 bits. Why?
512 / 128000 = 0.004
Once again we have a Tc value of 4 ms. Let’s try iPerf again:
CLIENT# iperf -c 192.168.2.2 -P 8
Here’s the result:
SERVER#
[SUM]  0.0-153.5 sec  2.25 MBytes   123 Kbits/sec
Seems our shaper is working fine, we get close to 128 Kbps. Let’s bump up the clock rate again:
R2(config)#interface Serial 0/0/0
R2(config-if)#clock rate 512000
We’ll shape to 50% of the available bandwidth again:
R1(config)#policy-map SHAPE_AVERAGE
R1(config-pmap)#class IPERF
R1(config-pmap-c)#shape average 256000
Here’s what it looks like on the router:
R1#show policy-map interface Serial 0/0/0
 Serial0/0/0 

  Service-policy output: SHAPE_AVERAGE

    Class-map: IPERF (match-all)
      8380 packets, 12339992 bytes
      5 minute offered rate 79000 bps, drop rate 0 bps
      Match: access-group name IPERF_CLIENT_SERVER
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/1304/0
      (pkts output/bytes output) 7076/10387712
      shape (average) cir 256000, bc 1024, be 1024
      target shape rate 256000
This time we see a Bc value of 1024:
1024 / 256000 = 0.004
Once again, Cisco IOS sets the Bc value so we end up with a Tc value of 4 ms. Let’s try iPerf again:
CLIENT# iperf -c 192.168.2.2 -P 8
SERVER#
[SUM]  0.0-93.8 sec  2.75 MBytes   246 Kbits/sec
This is looking good, our traffic is limited to 246 Kbps.
What about faster interfaces? Let’s try something with our FastEthernet interfaces between R1 and R2. Let’s change the static route so that R1 and R2 don’t use the serial links anymore:
R1(config)#no ip route 192.168.2.0 255.255.255.0 192.168.12.2
R1(config)#ip route 192.168.2.0 255.255.255.0 192.168.21.2
R2(config)#no ip route 192.168.1.0 255.255.255.0 192.168.12.1
R2(config)#ip route 192.168.1.0 255.255.255.0 192.168.21.1
Let’s see what kind of throughput we get without any shaper configured:
CLIENT# iperf -c 192.168.2.2 -P 8
SERVER#
[SUM]  0.0-10.2 sec   116 MBytes  95.4 Mbits/sec
The output above is what we would expect from a 100 Mbit link. Let’s shape this to 1 Mbit:
R1(config)#policy-map SHAPE_AVERAGE
R1(config-pmap)#class IPERF
R1(config-pmap-c)#shape average 1m
Instead of specifying the shape value in bits, you can also use “k” or “m” to specify Kbps or Mbps. Let’s activate it:
R1(config)#interface FastEthernet 0/0
R1(config-if)#service-policy output SHAPE_AVERAGE
What Bc value did the router calculate this time?
R1#show policy-map interface FastEthernet 0/0
 FastEthernet0/0 

  Service-policy output: SHAPE_AVERAGE

    Class-map: IPERF (match-all)
      0 packets, 0 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: access-group name IPERF_CLIENT_SERVER
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/0/0
      (pkts output/bytes output) 0/0
      shape (average) cir 1000000, bc 4000, be 4000
      target shape rate 1000000
We see a Bc value of 4000:
4000 / 1000000 = 0.004 ms.
Once again, the router prefers a Tc of 4 ms.
The most recent Cisco IOS versions always prefer a Tc of 4 ms and will calculate the Bc value accordingly. On older Cisco IOS versions it’s possible that you see higher Bc values with a Tc of 125 ms.
Let’s test Iperf again:
CLIENT~# iperf -c 192.168.2.2 -P 8
SERVER#
[SUM]  0.0-27.4 sec  3.12 MBytes   955 Kbits/sec
Great, our traffic is now shaped to 955 Kbps which is close enough to 1 Mbps.
So far we used the default Bc and Tc values that the router calculated for us. What if we have a requirement where we have to configure one of these values manually?
We can’t configure the Tc directly but we can change the Bc. Let’s say that we have a requirement where we have to set the Tc to 10 ms. How do we approach this?
Here’s the formula to calculate the Tc:
Bc = Tc * CIR
So in our case we want 10 ms:
10 ms * 1000 Kbps = 10.000 bits
Let’s configure our Bc value to 10.000 bits:
R1(config)#policy-map SHAPE_AVERAGE
R1(config-pmap)#class IPERF
R1(config-pmap-c)#shape average 1m ?
  <32-154400000>  bits per interval, sustained. Recommend not to configure, the
                  algorithm will fi
First we set the targetted bit rate and then we set the Bc value:
R1(config-pmap-c)#shape average 1m 10000
That should do it, let’s check the router:
R1#show policy-map interface FastEthernet 0/0
 FastEthernet0/0 

  Service-policy output: SHAPE_AVERAGE

    Class-map: IPERF (match-all)
      2496 packets, 3716912 bytes
      5 minute offered rate 19000 bps, drop rate 0 bps
      Match: access-group name IPERF_CLIENT_SERVER
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/189/0
      (pkts output/bytes output) 2307/3430766
      shape (average) cir 1000000, bc 10000, be 10000
      target shape rate 1000000
That’s all there is to it. Let’s try one more example, let’s say we want a Tc of 125 ms:
125 ms * 1000 Kbps = 125.000 bits
Let’s configure this:
R1(config)#policy-map SHAPE_AVERAGE
R1(config-pmap)#class IPERF
R1(config-pmap-c)#shape average 1000000 125000
Here’s what it looks like on the router:
R1#show policy-map interface FastEthernet 0/0
 FastEthernet0/0 

  Service-policy output: SHAPE_AVERAGE

    Class-map: IPERF (match-all)
      2496 packets, 3716912 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: access-group name IPERF_CLIENT_SERVER
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/189/0
      (pkts output/bytes output) 2307/3430766
      shape (average) cir 1000000, bc 125000, be 125000
      target shape rate 1000000
That’s it, you have now seen how to configure shaping and how to influence the Tc by setting different Bc values.

Conclusion

Thanks to the MQC, configuring shaping on Cisco IOS routers is pretty straightforward. You have now learned how to configure shaping and also how to influence the Tc by setting the correct Bc value.
In the next lesson, I will explain how “peak” shaping works which works a bit different compared to “average” shaping.
hostname R1
!
ip cef
!
interface FastEthernet0/0
 ip address 192.168.21.1 255.255.255.0
!
interface FastEthernet0/1
 ip address 192.168.1.254 255.255.255.0
!
interface Serial0/0/0
 ip address 192.168.12.1 255.255.255.0
!
ip route 192.168.2.0 255.255.255.0 192.168.21.2
!
end
hostname R2
!
ip cef
!
interface FastEthernet0/0
 ip address 192.168.21.2 255.255.255.0
!
interface FastEthernet0/1
 ip address 192.168.2.254 255.255.255.0
!
interface Serial0/0/0
 ip address 192.168.12.2 255.255.255.0
!
ip route 192.168.1.0 255.255.255.0 192.168.21.1
!
end


I hope you enjoyed this lesson, if you have any questions feel free to leave a comment below.

No comments:

Post a Comment