Introduction
============
This document describes the core of the WRR scheduler.

The WRR scheduler is a queuing discipline with classes. It has a build-in 
filter which assigns packets from or to different machines to different 
classes. It automatically creates a class for every (local) machine it sees 
a packet to/from.

Note that the scheduler throws away everything but IP and ARP traffic. It will 
not be difficult to change the source code to get a different behavior, however 
(you will need to modify the mac_classify function).


Parameters to the WRR qdisc
===========================
The WRR qdisc has the following parameters which should be specified at qdisc
creation time:
  
  <direction>
    This should be either "sour" or "dest".    
    It tells the WRR scheduler if it should assign packets to classes
    according to the source or destination address of the packets. If you are 
    setting WRR up for incoming traffic for your LAN you should specify dest.
    For outgoing you should specify sour.
  
  <classify>
    This should be either "ip", "mac" or "masq".
    It tells the WRR scheduler how it should classify packets.
    If it is "ip" it will use the IP address. If it is "mac" it will
    use the MAC adress. "mac" will only work for bridged packets, though, so
    non-bridged packets are mapped to a default class. Also "mac" it is 
    currently only supported on 2.2 kernels. Finally "masq" works like
    "ip", but masqgraded packets to the outside world are classified according
    to the IP address of the local machine they are comming from. "masq" should
    only be used when <classify> is "sour".
        
  <maxclasses>
    This is an upper limit of the number of classes that can be created.
    That is, how many different classes packets can be classified into.
    Or said in another way, an upper limit of the number of machines that
    may exists. Set this much higher than necessary. But not too high - it
    will use more memory.

  <proxymaxcon>
    This is used by the proxyremap package. In that case it should be set
    to the maximal number of concurrent connections the proxyserver can make.
    When using the proxyremap package a typical value here i 2048. Else
    it can be set to 0.

The following parameters can be changed dynamically:

  <wmode1>,<wmode2>
    These are described in the next section. Default value is 0.

Parameters to the WRR classes
=============================
Each class in the WRR scheduler has 8 parameters:

  weight1, min1, decr1, incr1,
  weight2, min2, decr2, incr2
  
The total weight used by the class when scheduling is weight1 times weight2. 
Every machine having sufficient demand will get bandwidth proportional
to this total weight.

The following will discuss the weight, min, decr and incr parameters.
They a valid both for the set of parameters ending with 1 and 2 since these are
handled in the same way.

  weight: (min<=weight<=1.0)
    As mentioned above the used weight of the class is proportional to
    this value. The default value is 1.0.
    
  min: (0<min)
    This is a lower bound for weight. 
    The default value for this parameter is 1.0.

  max: (0<max)
    This is a upper bound for weight. 
    The default value for this parameter is 1.0.
    
  incr: (0<=incr<1.0)
    Every second the weight parameter is incremented by this value. If
    weight1 reaches 1.0 it is not incremented further.
    The default value is 0.0.
    
  decr: (0<=decr<1.0)
    Every time a packet is sent the weight parameter is modified depending
    on the value of wmode for the qdisc:
    
      If wmode is 0:
        The weight parameter is not modified
      If wmode is 1:
        The weight parameter is decremented by decr*<packet size>
      If wmode is 2
        As if wmode is 1, but also multiply with number of machines waiting
	to transfer data
      If wmode is 3
        As if wmode is 1, but multiplied with the sum of the priorities of the
	machines waiting divided by the priority of this machine.
          
The values here can be used to decrease the weight for machines transferring
much data.


Hint on setting class parameters
================================
How should one set the values for the class parameters? In the example
the weights with number "1" are used to support machine which have very 
changing demand within a short time period. That is, to support machines 
for example surfing in contrast to machines transferring long files.

To find appropriate values to use for this define:

  min  = The value of the min1 parameter - that is the minimal value for
         for the weight1 parameter
  R    = Number of seconds it will take for weight1 to increase from min
         to 1.0 given the machine is not transferring anything.
  F    = Number of seconds it should take for the weight1 parameter to
         decrease from 1.0 to min1 given the machine is transferring with
	 the maximal posible speed.
  S    = Total speed of the link in bytes / second. This is the speed in
         Kbit/s multiplied with 128.
  
At my site we use min=0.5, R=600, F=600 and S=65536 (for a 512Kbit/s link).
We can approximate the discussed behavior with the following values:

  min1      = min
  incr1     = (1.0-min) / R
  decr1     = (1.0-min)*(1+F/R)/(F*S)
  wmode     = 3

So at my site we use the values:

  min1      = 0.5
  incr1     = 0.00083333333
  decr1     = 0.0000000254  
  wmode     = 3

The formula is derived here and you are probably not interested in 
reading this derivation:

  To make the bandwidth increase from min to 1.0 in R seconds we must have:
  
    1.0 - min = incr*R
  
  Suppose that there was only one machine and that it was transferring
  with full bandwidth. To get the right decreasing behavior we must have:

    min = 1.0 + incr*F - decr*F*S

  The first one gives:
  
    incr = (1.0-min) / R

  And then we have:    
  
    decr = ( 1.0 + incr*F - min ) / (F*S)
         = ( 1.0 + (1.0-min)*F/R - min ) / (F*S)
	 = (1.0-min)*(1+F/R)/(F*S)

  Now, more than one machine is using the line. That is why we set 
  wmode=3.


Running the tc program
======================
This section describes how to run the tc program to setup the parameters
described above. 

When creating a qdisc you should use the following syntax:

  tc qdisc add ... wrr <direction> <classify> <maxclasses> <proxymaxcon> \
                         [<wmode1>=0|1|2|3] [<wmode2>=0|1|2|3]
		       
Afterwards the wmode1 and wmode2 can be changed in the following way:

  tc qdisc change ... wrr [<wmode1>=0|1|2|3] [<wmode2>=0|1|2|3]

The parameters for a class can be changed in the ordinary way referring to
class handels:

  tc class change ... wrr [min1=<min1>] [min2=<min2>] ...

But it is also possible to change the values for a class associated with
a specified MAC or IP address:

  tc qdisc change ... wrr class <addr> [min1=<min1>] [min2=<min2>] ...

Where <addr> should be a MAC or IP address depending on the <classifyway>
parameter given when creating the WRR qdisc.


--------------------------------------------------------------------
This document was written by Christian Worm Mortensen, cworm@it-c.dk
