FairQ ALTQ for PF - Patch #1

Matthew Dillon dillon at apollo.backplane.com
Thu Apr 3 21:35:17 PDT 2008


    Ok, This is my first attempt at adding a fairq feature to ALTQ/PF.
    It isn't perfect yet, but it appears to work reasonably well.

	fetch http://apollo.backplane.com/DFlyMisc/fairq01.patch

    It isn't hierarchical (at least not yet), but you can specify multiple
    queues for each interface as long as you give them different priorities.

    Here is an example configuration:

altq on vke0 fairq bandwidth 500Kb queue { normal, fair }
queue fair priority 1 bandwidth 100Kb fairq(buckets 64) qlimit 50
queue normal priority 2 bandwidth 400Kb fairq(buckets 64, default) qlimit 50

pass out on vke0 inet proto tcp from any to any keep state queue normal
pass out on vke0 inet proto tcp from any to 216.240.41.28 keep state queue fair

    Here is how it works:

    * The queues are scanned from highest priority to lowest priority.

    * If the packet bandwidth on the queue does not exceed the bandwidth
      parameter and a packet is available, a packet will be chosen from
      that queue.

    * If a packet is available but the queue has exceeded the specified
      bandwidth, the next lower priority queue is scanned (and so forth).

    * If NO lower priority queues either have packets or are all over the
      bandwidth limit, then a packet will be taken from the highest priority
      queue with a packet ready.

    * Packet rate can exceed the queue bandwidth specification (but
      will not exceed the interface bandwidth specification, of course),
      but under full saturation the average bandwidth for any given
      queue will be limited to the specified value.

    Here is how the fair queueing works:

    * You MUST specify 'keep state' in the related rules.

    * keep state 'connections' will be given a fingerprint hash code which
      will be used to enqueue the mbuf in one of the N buckets (64 in our
      example) for each fair queue.

    * When PF request's a packet from the fairq, a packet will be selected
      from each of the 64 buckets in a round-robin fashion.

      Thus if you have a very hungy connection, it will not be able to
      steal all the bandwidth (or queue up tons of packets to the actual
      interface) from other connections within the queue.

    Caveats and issues:

    (1) The qlimit is per-bucket.  So 64 buckets x 50 packets is, worst case,
	3200 packets.  It's unlikely this would ever occur, but it's an issue
	that I haven't dealt with yet.

    (2) Due to limitations on the number of buckets, multiple connections
	can end up in the same bucket.  If one of those connections is a
	heavy hitter, the others will suffer.

	This could probably be fixed with further sorting or perhaps a
	different topology (e.g. like a tree instead of a fixed array).

    Please Test!  I have this running on my router box right now and
    it appears to work very well.

						-Matt






More information about the Kernel mailing list