|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +DEVICE="ppp0" |
| 4 | +NUM_HOST_BUCKETS=4 |
| 5 | +NUM_FLOW_BUCKETS=64 |
| 6 | + |
| 7 | +# All rates are kbit/sec. |
| 8 | +# RATE should be set to just under your upload link rate. |
| 9 | +RATE="620" |
| 10 | +# TODO - take RATE /3 to get the below ?? |
| 11 | +# Below three rates should add up to RATE. |
| 12 | +RATE_1="220" |
| 13 | +RATE_2="220" |
| 14 | +RATE_3="180" |
| 15 | + |
| 16 | +FIFO_LEN=4 |
| 17 | +PERTURB=15 |
| 18 | +OVERHEAD=40 # PPPoE |
| 19 | +R2Q=2 |
| 20 | + |
| 21 | +############### |
| 22 | +############### |
| 23 | + |
| 24 | +function dec_to_hex { |
| 25 | + echo `printf %x $1` |
| 26 | +} |
| 27 | + |
| 28 | +function drr { |
| 29 | + PARENT=$1 |
| 30 | + HANDLE=$2 |
| 31 | + |
| 32 | + # Create the QDisc. |
| 33 | + tc qdisc add dev ${DEVICE} parent ${PARENT} handle ${HANDLE} drr |
| 34 | + |
| 35 | + # Create NUM_FLOW_BUCKETS classes. |
| 36 | + for J in `seq ${NUM_FLOW_BUCKETS}`; do |
| 37 | + tc class add dev ${DEVICE} parent ${HANDLE} classid ${HANDLE}:`dec_to_hex ${J}` drr |
| 38 | + tc qdisc add dev ${DEVICE} parent ${HANDLE}:`dec_to_hex ${J}` pfifo limit ${FIFO_LEN} |
| 39 | + done |
| 40 | + |
| 41 | + # Add a filter to direct the packets. |
| 42 | + tc filter add dev ${DEVICE} prio 1 protocol ip parent ${HANDLE}: handle 1 flow hash keys src,dst,proto,proto-src,proto-dst divisor ${NUM_FLOW_BUCKETS} perturb ${PERTURB} baseclass ${HANDLE}:1 |
| 43 | +} |
| 44 | + |
| 45 | +function sfq { |
| 46 | + PARENT=$1 |
| 47 | + HANDLE=$2 |
| 48 | + |
| 49 | + tc qdisc add dev ${DEVICE} parent ${PARENT} handle ${HANDLE} sfq perturb ${PERTURB} limit ${FIFO_LEN} |
| 50 | +} |
| 51 | + |
| 52 | +# Get the dividied rate values for use later. |
| 53 | +DIV_RATE=`expr ${RATE} / ${NUM_HOST_BUCKETS}` |
| 54 | +DIV_RATE_1=`expr ${RATE_1} / ${NUM_HOST_BUCKETS}` |
| 55 | +DIV_RATE_2=`expr ${RATE_2} / ${NUM_HOST_BUCKETS}` |
| 56 | +DIV_RATE_3=`expr ${RATE_3} / ${NUM_HOST_BUCKETS}` |
| 57 | + |
| 58 | +echo "DIV_RATE:" ${DIV_RATE} |
| 59 | +echo "DIV_RATE_1:" ${DIV_RATE_1} |
| 60 | +echo "DIV_RATE_2:" ${DIV_RATE_2} |
| 61 | +echo "DIV_RATE_3:" ${DIV_RATE_3} |
| 62 | + |
| 63 | + |
| 64 | +# Delete the existing qdiscs etc if they exist. |
| 65 | +tc qdisc del dev ${DEVICE} root |
| 66 | + |
| 67 | +# HTB QDisc at the root. Default all traffic into the prio qdisc. |
| 68 | +tc qdisc add dev ${DEVICE} root handle 1: htb r2q ${R2Q} |
| 69 | + |
| 70 | +# Create a top level class with the max rate. |
| 71 | +tc class add dev ${DEVICE} parent 1: classid 1:1 htb rate ${RATE}kbit linklayer atm overhead ${OVERHEAD} |
| 72 | + |
| 73 | +### |
| 74 | +# Create NUM_HOST_BUCKETS classes within the top-level class. |
| 75 | +### |
| 76 | +for HOST_NUM in `seq ${NUM_HOST_BUCKETS}`; do |
| 77 | + echo "Create host class:" $HOST_NUM |
| 78 | + |
| 79 | + QID=`expr ${HOST_NUM} '+' 9` # 1+9=10 - Start classes at 10. |
| 80 | + tc class add dev ${DEVICE} parent 1:1 classid 1:${QID} htb rate ${DIV_RATE}kbit ceil ${RATE}kbit prio 0 linklayer atm overhead ${OVERHEAD} |
| 81 | + |
| 82 | + ### |
| 83 | + # Within each top level class add three classes, high, normal and low priority. |
| 84 | + ### |
| 85 | + QID_1=`expr $QID '*' 100 + 1` |
| 86 | + tc class add dev ${DEVICE} parent 1:${QID} classid 1:${QID_1} htb rate ${DIV_RATE_1}kbit ceil ${RATE}kbit prio 0 linklayer atm overhead ${OVERHEAD} |
| 87 | + QID_2=`expr $QID '*' 100 + 2` |
| 88 | + tc class add dev ${DEVICE} parent 1:${QID} classid 1:${QID_2} htb rate ${DIV_RATE_2}kbit ceil ${RATE}kbit prio 1 linklayer atm overhead ${OVERHEAD} |
| 89 | + QID_3=`expr $QID '*' 100 + 3` |
| 90 | + tc class add dev ${DEVICE} parent 1:${QID} classid 1:${QID_3} htb rate ${DIV_RATE_3}kbit ceil ${RATE}kbit prio 2 linklayer atm overhead ${OVERHEAD} |
| 91 | + |
| 92 | + ### |
| 93 | + # Within each priority class add a QDisc for flow fairness. |
| 94 | + ### |
| 95 | + QID_1_1=`expr ${QID_1} + 1` |
| 96 | + drr 1:${QID_1} ${QID_1_1} |
| 97 | + #sfq 1:${QID_1} ${QID_1_1} |
| 98 | + |
| 99 | + QID_2_1=`expr ${QID_2} + 1` |
| 100 | + drr 1:${QID_2} ${QID_2_1} |
| 101 | + #sfq ${QID_2} ${QID_2_1} |
| 102 | + |
| 103 | + QID_3_1=`expr ${QID_3} + 1` |
| 104 | + drr 1:${QID_3} ${QID_3_1} |
| 105 | + #sfq 1:${QID_3} ${QID_3_1} |
| 106 | + |
| 107 | + ### |
| 108 | + # Add filters to classify based on the TOS bits. |
| 109 | + # Only mask against the three (used) TOS bits. The final two bits are used for ECN. |
| 110 | + # TODO: Just look at delay 100 and throughput 001, everthing else to default. |
| 111 | + ### |
| 112 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x00 0x1c flowid 1:${QID_2} |
| 113 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x04 0x1c flowid 1:${QID_2} |
| 114 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x08 0x1c flowid 1:${QID_3} |
| 115 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x0c 0x1c flowid 1:${QID_3} |
| 116 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x10 0x1c flowid 1:${QID_1} |
| 117 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x14 0x1c flowid 1:${QID_1} |
| 118 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x18 0x1c flowid 1:${QID_2} |
| 119 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0x1c 0x1c flowid 1:${QID_2} |
| 120 | + |
| 121 | + # Diffserv expedited forwarding. Put this in the high priority class. |
| 122 | + tc filter add dev ${DEVICE} parent 1:${QID} protocol ip prio 10 u32 match ip tos 0xb8 0xfc flowid 1:${QID_1} |
| 123 | +done |
| 124 | + |
| 125 | +# Send everything that hits the top level QDisc to the top class. |
| 126 | +tc filter add dev ${DEVICE} prio 1 protocol ip parent 1:0 u32 match u32 0 0 flowid 1:1 |
| 127 | + |
| 128 | +# From the top level class hash into the host classes. |
| 129 | +tc filter add dev ${DEVICE} prio 1 protocol ip parent 1:1 handle 1 flow hash keys src divisor ${NUM_HOST_BUCKETS} perturb ${PERTURB} baseclass 1:10 |
0 commit comments