Previous

Content  

Next


3.8. Afhtb

 

In the original distribution this example was implemented using cbq. Our version is implemented using the new queuing discipline htb. The modify example's script is as follows. Because the example is long and a little bit complicated, I re-arrange the commands to simplify explanation and a mark with a blue number identify each command, or group of them:


 
#!/bin/bash

# 1 --- Main dsmark
tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 set_tc_index

# 2 --- Main dsmark classifier
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
tcindex mask 0xfc shift 2 pass_on

# --- Main dsmark classifier's elements

# 3 --- AF Class 1
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 10 tcindex classid 1:111
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 12 tcindex classid 1:112
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 14 tcindex classid 1:113

# 4 --- AF Class 2
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 18 tcindex classid 1:121
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 20 tcindex classid 1:122
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 22 tcindex classid 1:123

# 5 --- AF Class 3
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 26 tcindex classid 1:131
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 28 tcindex classid 1:132
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 30 tcindex classid 1:133

# 6 --- AF Class 4
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 34 tcindex classid 1:141
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 36 tcindex classid 1:142
tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
handle 38 tcindex classid 1:143
 
   

 

# 7 --- BE
tc filter add dev eth0 parent 1:0 protocol ip prio 2 \
handle 0 tcindex mask 0 classid 1:1

# 8 --- Main htb qdisc
tc qdisc add dev eth0 parent 1:0 handle 2:0 htb

# 9 --- Main htb class
tc class add dev eth0 parent 2:0 classid 2:1 htb rate 10Mbit ceil 10Mbit

# 10 --- Main htb classifier
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
tcindex mask 0xf0 shift 4 pass_on

# --- Main htb classifier's elements

# 11 --- AF Class 1
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
handle 1 tcindex classid 2:10

# 12 --- AF Class 2
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
handle 2 tcindex classid 2:20

# 13 --- AF Class 3
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
handle 3 tcindex classid 2:30

# 14 --- AF Class 4
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
handle 4 tcindex classid 2:40

# 15 --- BE
tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
handle 0 tcindex classid 2:50

# 16 --- AF Class 1 specific setup---
tc class add dev eth0 parent 2:1 classid 2:10 htb rate 1500Kbit ceil 10Mbit
tc qdisc add dev eth0 parent 2:10 gred setup DPs 3 default 2 grio

# 17 --- AF Class 1 DP 1---
tc qdisc change dev eth0 parent 2:10 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 1 probability 0.02 prio 2

# 18 --- AF Class 1 DP 2---
tc qdisc change dev eth0 parent 2:10 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 2 probability 0.04 prio 3

# 19 --- AF Class 1 DP 3---
tc qdisc change dev eth0 parent 2:10 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 3 probability 0.06 prio 4

# 20 --- AF Class 2 specific setup---
tc class add dev eth0 parent 2:1 classid 2:20 htb rate 1500Kbit ceil 10Mbit
tc qdisc add dev eth0 parent 2:20 gred setup DPs 3 default 2 grio

# 21 --- AF Class 2 DP 1---
tc qdisc change dev eth0 parent 2:20 gred limit 60KB min 15KB max 45KB burst 20 \
avpkt 1000 bandwidth 10Mbit DP 1 probability 0.02 prio 2

# 22 --- AF Class 2 DP 2---
tc qdisc change dev eth0 parent 2:20 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 2 probability 0.04 prio 3

# 23 --- AF Class 2 DP 3---
tc qdisc change dev eth0 parent 2:20 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 3 probability 0.06 prio 4

# 24 --- AF Class 3 specific setup---
tc class add dev eth0 parent 2:1 classid 2:30 htb rate 1500Kbit ceil 10Mbit
tc qdisc add dev eth0 parent 2:30 gred setup DPs 3 default 2 grio

# 25 --- AF Class 3 DP 1---
tc qdisc change dev eth0 parent 2:30 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 1 probability 0.02 prio 2

# 26 --- AF Class 3 DP 2---
tc qdisc change dev eth0 parent 2:30 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 2 probability 0.04 prio 3

# 27 --- AF Class 3 DP 3---
tc qdisc change dev eth0 parent 2:30 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 3 probability 0.06 prio 4

# 28 --- AF Class 4 specific setup---
tc class add dev eth0 parent 2:1 classid 2:40 htb rate 1500Kbit ceil 10Mbit
tc qdisc add dev eth0 parent 2:40 gred setup DPs 3 default 2 grio

# 29 --- AF Class 4 DP 1---
tc qdisc change dev eth0 parent 2:40 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 1 probability 0.02 prio 2

# 30 --- AF Class 4 DP 2---
tc qdisc change dev eth0 parent 2:40 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 2 probability 0.04 prio 3

# 31 --- AF Class 4 DP 3---
tc qdisc change dev eth0 parent 2:40 gred limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit DP 3 probability 0.06 prio 4

# 32 ------BE Queue setup------
tc class add dev eth0 parent 2:1 classid 2:50 htb rate 1500Kbit ceil 10Mbit
tc qdisc add dev eth0 parent 2:50 red limit 60KB min 15KB max 45KB \
burst 20 avpkt 1000 bandwidth 10Mbit probability 0.4


The precedence blue number above are matched with the numbers below:
A very important note: to simplify the script understanding, I wrote some commands before some that require the firsts. For example, to configure the classifier element in the command 11 above:
 
  tc filter add dev eth0 parent 2:0 protocol ip prio 1 handle 1 tcindex classid 2:10

You need to create *first* the htb class 2:10, as in the command 16 above, that is:

  tc class add dev eth0 parent 2:1 classid 2:10 htb rate 1500Kbit ceil 10Mbit
The relative position was moved because it is easier to understand the commands when they are presented in this (natural) order; check your script to avoid a command from being executed before some other that it depends to.
 
  1. The main dsmark queuing discipline is configured. Because set_tc_index is indicated, the discipline copies the DS field from the entering packet onto the tc_index field.
     
  2. The main dsmark's attached classifier is configured. It takes a copy of the value contained in the tc_index field, applies on it the bitwise operation (value & 0xfc) >> 2 and passes down the result to the classifier's elements.
     
  3. Classifier's elements which correspond to the differentiated service class AF1. The DS-field values of the classes AF11, AF12 and AF13 are 0x28, 0x30 and 0x38 respectively. Applying on these values the bitwise operation indicated in 2 (above), the new values will be 0xa, 0xc and 0xe, which correspond to the decimal values 10, 12 and 14 respectively. These values (10,12,14) will be matched by the classifier's elements, for example: handle 10 tcindex matches the value 10. The classifier's element returns back to the dsmark queuing discipline the minor-value of its class identifier. Then handle 10 tcindex classid 1:111, will return the class identifier 111; but, be careful, 111 just means 0x0111. *
     
  4. Similar as number 3 above, but for the differentiated service class AF2. This time classes AF21, AF22 and AF23 are 0x48, 0x50 and 0x58 respectively. After the bitwise operation the new values will be 0x12, 0x14 and 0x16, which correspond to the decimal values 18, 20 and 22 respectively. These values will be matched by the classifier's elements returning the class identifier minor-values 121, 122 and 123.
  1. Similar as number 3 above, but for the differentiated service class AF3. This time classes AF31, AF32 and AF33 are 0x68, 0x70 and 0x78 respectively. After the bitwise operation the new values will be 0x1a, 0x1c and 0x1e, which correspond to the decimal values 26, 28 and 30 respectively. These values will be matched by the classifier's elements returning the class identifier minor-values 131, 132 and 133.
     
  2. Similar as number 3 above, but for the differentiated service class AF4. This time classes AF41, AF42 and AF43 are 0x88, 0x90 and 0x98 respectively. After the bitwise operation the new values will be 0x22, 0x24 and 0x26, which correspond to the decimal values 34, 36 and 38 respectively. These values will be matched by the classifier's elements returning the class identifier minor-values 141, 142 and 143.
     
  3. Similar as number 3 above, but for the differentiated service class BE (best-effort). Class BE is DS field 0x0. After the bitwise operation the new value continue being 0x0. This value will be matched by this classifier's element (handle 0 tcindex) returning the class identifier minor-values 1.
  1. The main htb queuing discipline is configured here as a child of the main dsmark queuing discipline.
     
  2. htb queuing discipline requires a main class to distribute bandwidth and implement link-sharing. This class is configured here as the classid 2:1, having a rate and ceiling bandwith of 10 Mbps.
     
  3. The htb main classifier is configured in this line of our long script. Be specially careful with the bitwise operation implement by this pet. It masks the classes with 0xf0 (11110000), stripping this way the 4-rightmost bits, and then applies a 4-bit right shift; this means, it gets the 4-leftmost bits of the classid value. What do you thing is going to occur when you apply this monster to one of the classid returned by the filter's elements identified above by the numbers 3, 4, 5, 6 and 7?. Let's take an example. I like the second element of the AF Class 3 filter (identified by the number 5 above). The second element is:

    tc filter add dev eth0 parent 1:0 protocol ip prio 1 \
    handle 28 tcindex classid 1:132

    Then, this little beetle returns (for the dsmark queuing discipline setting the tc_index field value) the classid 132 (minor-value). Applying over this the bitwise operation we have (this will be occurring when the main classifier in this explanation puts its hands over the tc_index field value previously set by the dsmark queuing discipline):

    0x0132 & 0x00f0 = 0000 0001 0011 0010 & 0000 0000 1111 0000 =
                      0000 0000 0011 0000 = 0x30

    0x30 = 0011 0000 >> 4 = 0000 0011 = 0x3

    Eureka!! What do we have here? Just the AF class 3 identification. Do not forget that this precious value will be passed down to the filter's elements of this classifier. See below, under numbers 11, 12, 13, 14 and 15.

    That's the reason why I insisted before in handling very well these bit manipulating operations.
 
   

 

  1. The first filter's element of the htb's main classifier. This element, and the next four below, are going to receive the value passed down from the htb's main classifier. The value passed, will be matched against the tcindex handle managed by each element. For this element (the first one), the value to be matched is 1 (handle 1 tcindex), see the command above, please. Okay. This element matches the value 1. And, what is the meaning of receiving a value == 1. Just that the class of the packet is AF class 1. Then, this filter element will match packet belonging to the DS class AF1.

    Nice!! But, what is the job entrusted to this filter element? Let's have a look to the command:

    tc filter add dev eth0 parent 2:0 protocol ip prio 1 \
    handle 1 tcindex classid 2:10

    Our friend is then in charge to send these packets (class AF1 packets) to the htb class identified with the classid 2:10. Ja, ja...  little by little we put our AF1 class packets in the place we want, just in the htb class 2:10 where we can control them. But, keep on reading, this htb class is explained below...
     
  2. Same as 11 for the AF2 class. Goes fast now, doesn't it? Using htb's class 2:20 this time.
     
  3. Same as 11 for the AF3 class. Using htb's class 2:30.
     
  4. Same as 11 for the AF4 class. Using htb's class 2:40.
     
  5. Same as 11 for the BE class. Using htb's class 2:50. Be careful, the classid matches by this element is 0x0 which correspond to the BE filter identified above with the number 7. Why?
     
  6. The second htb queuing discipline's class is added (the first class was the main class 2:1 configured in 9). This command corresponds to the htb class 2:10 which will be in charge to receive packets from DS class AF1 (see explanation above, under 11). Using the htb link-sharing capacity, this class is being configured for a normal rate of 1500 kbps and a ceiling rate of 10 Mbps.

    Immediately, using a second command, a gred queuing discipline is attached to this class. The gred is configured with 3 virtual queues, being the queue number 2 the default queue and using a priority buffer scheme (grio). The three virtual queues are configured using the commands 17, 18 and 19. See below.
     
  7. The htb class 2:10's gred virtual queue number 1 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF11.
     
  8. The htb class 2:10's gred virtual queue number 2 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF12.
     
  9. The htb class 2:10's gred virtual queue number 3 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF13.
     
  10. Now is the turn for adding a new htb link-sharing class. This command corresponds to the htb class 2:20 which will be in charge to receive packets from DS class AF2 (see explanation above, under 11). This class is being configured for a normal rate of 1500 kbps and a ceiling rate of 10 Mbps.

    Same as under 16, immediately, using a second command, a gred queuing discipline is attached to this class. Again, the gred is configured with 3 virtual queues, being the queue number 2 the default queue and using a priority buffer scheme (grio). The three virtual queues are configured using the commands 21, 22 and 23. See below.
     
  11. The htb class 2:20's gred virtual queue number 1 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF21.
     
  12. The htb class 2:20's gred virtual queue number 2 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF22.
     
  13. The htb class 2:20's gred virtual queue number 3 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF23.
     
  14. Again, the turn is for adding a new htb link-sharing class. This command corresponds to the htb class 2:30 which will be in charge to receive packets from DS class AF3 (see explanation above, under 11). This class is being configured for a normal rate of 1500 kbps and a ceiling rate of 10 Mbps.

    Same as under 16, immediately, using a second command, a gred queuing discipline is attached to this class. Again, the gred is configured with 3 virtual queues, being the queue number 2 the default queue and using a priority buffer scheme (grio). The three virtual queues are configured using the commands 25, 26 and 27. See below.
     
  15. The htb class 2:30's gred virtual queue number 1 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF31.
     
  16. The htb class 2:30's gred virtual queue number 2 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF32.
     
  17. The htb class 2:30's gred virtual queue number 3 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF33.
     
  18. Again, the turn is for adding a new htb link-sharing class. This command corresponds to the htb class 2:40 which will be in charge to receive packets from DS class AF4 (see explanation above, under 11). This class is being configured for a normal rate of 1500 kbps and a ceiling rate of 10 Mbps.

    Same as under 16, immediately, using a second command, a gred queuing discipline is attached to this class. Again, the gred is configured with 3 virtual queues, being the queue number 2 the default queue and using a priority buffer scheme (grio). The three virtual queues are configured using the commands 29, 30 and 31. See below.
     
  19. The htb class 2:40's gred virtual queue number 1 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF41.
     
  20. The htb class 2:40's gred virtual queue number 2 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF42.
     
  21. The htb class 2:40's gred virtual queue number 3 is configured here. This virtual queue will be in charge of dealing with packets belonging to the DS class AF43.
     
  22. Finally, the last htb link-sharing class is added. This command corresponds to the htb class 2:50 which will be in charge to receive packets from DS class BE (see explanation above, under 11). This class is being configured for a normal rate of 1500 kbps and a ceiling rate of 10 Mbps.

    Immediately, using a second command, a red queuing discipline (be careful, is a red, not a gred queueing discipline) is attached to this class. This queue is individualy configured as it was a gred virtual queue.
Well, fine. The commands are explained. But, I think that two additional pieces of information could help to understand well enough how this stuff makes its work. Then, we are going to add an scheme (it helps more than a hundred of words) and an explanation of how a selected packet flows throughout the discipline (to understand how our tiny friend travels and is treated when it is enough courageous to cross, alone?, with some similars? our bewitched Linux router).

If you have a 17 inches screen the scheme is just here

In the scheme we are trying to explain, as an example, how a DS class AF11 packet flows throughout the queuing discipline. The packet flow is explained, step by step, as follows (the small blue number at the right is related to the commands in the script above).

How a packet flows throughout the dsmark queuing discipline

  1. The AF11 packet enters the dsmark queuing discipline by the left (this is not really true, it's just a way to understand the diagram). Its TOS field contains the value 0x28. (1)
  2. The TOS field value is copied by the dsmark queuing discipline onto the skb->tc_index field. (1)
  3. The dsmark queuing discipline's main classifier reads the skb->tc_index value (0x28) and applies the bitwise operation: 0x28 & 0xfc >> 2 ; the result of this operation is 0xa. (2)
  4. This value (0xa) which corresponds to decimal 10, is passed down to the dsmark's main classifier elements. The first of these elements matches the decimal 10 value and returns back the class id value 0x111 to the dsmark queuing discipline. The dsmark queuing discipline then copies back this value again onto the skb->tc_index field. (3)
  5. The packet enters the htb queuing discipline. (8)
  6. The htb queuing discipline's main classifier reads the skb->tc_index value (0x111) and applies the bitwise operation: 0x111 & 0xf0 >> 4 ; the result of this operation is 0x1. (10)
  7. This value (0x1) which corresponds to decimal 1, is passed down to the htb's main classifier elements. The first of these elements matches the decimal 1 value and returns back the class id value 10 to the htb queuing discipline. (11)
  8. The htb queuing discipline then looks for this class number (10) in its child classes; it finds the class 2:10 and it puts the packet on it. Because this class is rated to 1500kbps, the AF11 packets are then allowed to flow up to 1500kbps. (16)
  9. The packet enters the gred queuing discipline. (16)
  10. The gred queuing discipline needs to know in which virtual queue to place the packet; to do this it reads the packet's buffer skb->tc_index field value. The value 0x111 is found. The gred queuing discipline then uses the last four bits of this number to select a VQ. Last four bits correspond to the value 0x1. Then the VQ number 1 is selected. The AF11 packets are then subjugated to a dropping probability of 0.02 (2%) when being buffered on this VQ. (17)
  11. Finally the packet leave the gred, htb and dsmark queuing disciplines. Because the dsmark is configured as classless in this configuration, no additional transformation is applied to the packet's DS field when leaving the dsmark queuing discipline. The packet is then forwarded using the same DS class it had when entering the discipline.
 
   

 

Okay, fellows. I really hope this explanation had been good enough to having clear this DS on Linux scheme. Our next step will be ef-prio.
 
* Please, make your homework, have a read to the previous chapters...

   


Previous

Content  

Next