Examples for using the sch_hfsc qdisc

A) wireline setup

At first any currently installed qdisc is removed (if it exists):

illiac:~ # tc qdisc del dev eth1 root

Then we display the help screen for the qdisc:

illiac:~ # tc qdisc add dev eth1 root hfsc help
Hierarchical Fair Service Curve Scheduler (H-FSC)

Usage: ... hfsc bandwidth BPS [estint SIZE] [varrate]
               [wireless] [wchmon NAME] [reducebad PERCENT]

  bandwidth   total bandwidth of the interface
              (for wireless LAN: max. expected total link throughput
               e.g. about 5.0 MBit/s for 11 Mbit/s card,
                    about 1.4 MBit/s for 2 Mbit/s card)
  varrate     use variable bandwidth adaption
  estint      size of interval for bandwidth estimation/averaging
  wireless    enable wireless channel monitoring/error rate estimation
  wchmon      install wireless channel monitor NAME on the target device
  reducebad   percentage of the additional bandwidth which a class needs
              because of retransmissions/rate adaption taken into account
              when scheduling in an overload state
hfsc: bandwidth is required parameter.
illiac:~ #

(If the kernel/iproute2 was compiled without the wireless scheduling options enabled, the wireless, wchmon and reducebad options will be missing, since they are only valid for wireless networking devices which have a wireless channel monitor attached - as in the second example.)

And the help screen for H-FSC classes:

illiac:~ # tc class add hfsc help
Hiererchical Fair Service Curve Scheduler (H-FSC)

Class parameters: [sc M1 D M2] [rt M1 D M2] [ls M1 D M2] [dc M1 D M2]
                  [pshare PERCENT] [grate BPS] [default] [help] [sync]

  sc              defines a service curve which consists of a two linear
                  pieces: up to delay D (in ms) with slope M1 and with
                  slope M2 afterwards (equal to defining a real-time and
                  a link-sharing curve with the same parameters)
  rt              defines a real-time service curve with parameters M1, D, M2
  ls              defines a link-sharing service curve
                  (NULL link-sharing curve can be used to shape bandwidth)
  dc              defines a packet drop curve
  pshare          defines a linear link-sharing curve with PERCENT of the total
                  bandwidth (equal to a linear [ls 0 0 M2] curve)
  grate           defines a linear real-time service curve with a rate of BPS
                  (equivalent to a linear [rt 0 0 M2] real-time curve
  default         specify this class as the (new) default class
  sync            this class is a wireless synchronization class

illiac:~ #

(The sync option is only available if wireless scheduling support is enabled.)
 

The scheduler module is loaded (optional  - if kernel is configured properly this will be done automagically):

illiac:~ # insmod sch_hfsc
Using /lib/modules/2.4.13/kernel/net/sched/sch_hfsc.o
illiac:~ #

In /var/log/messages you will find the following messages:

Nov  5 23:00:45 illiac kernel: Hierarchical Fair Service Curve Scheduler (H-FSC) [Oct 31 2001 18:45:57]
Nov  5 23:00:45 illiac kernel: H-FSC: -- compiled with wireless scheduling extensions --
Nov  5 23:00:45 illiac kernel: H-FSC: --        compiled with debugging support       --

The qdisc is attached to an interface (eth1) with a bandwidth of 10Mbit:

illiac:~ # tc qdisc add dev eth1 root handle 10:0 hfsc bandwidth 10Mbit

Then we add three child classes of which the first class is the default class:

Note: This setup is for demonstration purposes only. The limitation of the default class makes it easy to demonstrate the schedulers behaviour even without installing any filters since all traffic of the default class is limited to a very low rate.

illiac:~ # tc class add dev eth1 parent 10:0 classid 10:1 hfsc [rt 0 0 20kbit] default
illiac:~ # tc class add dev eth1 parent 10:0 classid 10:2 hfsc [sc 5Mbit 10ms 3Mbit]
illiac:~ # tc class add dev eth1 parent 10:0 classid 10:3 hfsc [sc 0 10ms 5Mbit]

The statistics about the configured classes are displayed:

illiac:~ # tc -s class show dev eth1
class hfsc 10: root  [rt  1289062bps 0ms 1289062bps]  [ls  1289062bps 0ms 1289062bps]  sync
total service received: 0  realtime-service received: 5572
transmitted: 5572  dropped: 0  queue length: 0  period: 58
internal state - d: 876782574230  e: 876782574156  vt: 0  k: 0

class hfsc 10:1 parent 10:  [rt  0bps 0ms 2517bps]  default
total service received: 19012  realtime-service received: 19012
transmitted: 19012  dropped: 0  queue length: 0  period: 198
internal state - d: 877215240646  e: 877215202365  vt: 0  k: 0

class hfsc 10:2 parent 10:  [rt  644531bps 10ms 386718bps]  [ls  644531bps 10ms
386718bps]
total service received: 0  realtime-service received: 0
transmitted: 0  dropped: 0  queue length: 0  period: 0
internal state - d: 0  e: 0  vt: 0  k: 0

class hfsc 10:3 parent 10:  [rt  0bps 10ms 515625bps]  [ls  0bps 10ms 515625bps]
total service received: 0  realtime-service received: 0
transmitted: 0  dropped: 0  queue length: 0  period: 0
internal state - d: 0  e: 0  vt: 0  k: 0

illiac:~ #
 

As with all other queuing disciplines the packets are classified by using filters. The following installs a filter for packets with the destination IP address 192.168.23.1 for class 10:2 and with the destination IP address 192.168.23.2 for class 10:3. All other classes are put in the default class.

illiac:~ # tc filter add dev eth1 parent 10:0 protocol ip prio 100 u32 match ip
dst 192.168.23.1 flowid 10:2
illiac:~ # tc filter add dev eth1 parent 10:0 protocol ip prio 100 u32 match ip
dst 192.168.23.2 flowid 10:3

Show the installed filters:

illiac:~ # tc filter show dev eth1
filter parent 10: protocol ip pref 100 u32
filter parent 10: protocol ip pref 100 u32 fh 800: ht divisor 1
filter parent 10: protocol ip pref 100 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 10:2
  match c0a81701/ffffffff at 16
filter parent 10: protocol ip pref 100 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 10:3
  match c0a81702/ffffffff at 16
illiac:~ #
 
 
 

B) wireless setup

Remove any existing qdisc on the interface:

illiac:~ # tc qdisc del dev eth1 root

Load a wireless channel monitor module:

illiac:~ # insmod wchmon_driver
Using /lib/modules/2.4.13/kernel/net/sched/wchmon_driver.o
illiac:~ #

The following will be logged to /var/log/messages:

Nov  5 23:12:32 illiac kernel: Wireless Channel-Monitor (driver), LW [Oct 31 2001 12:52:23]

The wireless channel monitor is configured with a specific calibration profile for the installed wireless card:

illiac:~ # cp lucent_avaya_10_8.cnf /proc/net/wchmon_gtr_map

The wirless qdisc is attached to the interface and configured to use the wireless channel monitor of type driver:

illiac:~ # tc qdisc add dev eth1 root handle 10:0 hfsc bandwidth 5Mbit wireless wchmon driver
 

Classes are configured:


illiac:~ # tc class add dev eth1 parent 10:0 classid 10:1 hfsc [rt 0 0 20kbit]
[dc 0 0 19kbit] default
illiac:~ # tc class add dev eth1 parent 10:0 classid 10:2 hfsc [sc 0 0 3Mbit] sync
illiac:~ # tc class add dev eth1 parent 10:2 classid 10:21 hfsc [sc 0 0 1Mbit]
illiac:~ # tc class add dev eth1 parent 10:2 classid 10:22 hfsc [sc 0 0 2Mbit]

illiac:~ # tc -s class show dev eth1
class hfsc 10: root  [rt  644531bps 0ms 644531bps]  [ls  644531bps 0ms 644531bps]  sync
total service received: 0  realtime-service received: 620053
transmitted: 6454  dropped: 0  queue length: 0  period: 67
internal state - d: 878164635498  e: 878164635349  vt: 0  k: 0

class hfsc 10:1 parent 10:  [rt  0bps 0ms 2517bps]  default
total service received: 124012  realtime-service received: 124012
transmitted: 124012  dropped: 16086  queue length: 0  period: 1602
internal state - d: 880706021919  e: 880705983638  vt: 0  k: 880756959170

class hfsc 10:2 parent 10:  [rt  0bps 0ms 386718bps]  [ls  0bps 0ms 386718bps]
sync
total service received: 0  realtime-service received: 0
transmitted: 0  dropped: 0  queue length: 0  period: 0
internal state - d: 0  e: 0  vt: 0  k: 0

class hfsc 10:21 parent 10:2  [rt  0bps 0ms 128906bps]  [ls  0bps 0ms 128906bps]
total service received: 0  realtime-service received: 0
transmitted: 0  dropped: 0  queue length: 0  period: 0
internal state - d: 0  e: 0  vt: 0  k: 0

class hfsc 10:22 parent 10:2  [rt  0bps 0ms 257812bps]  [ls  0bps 0ms 257812bps]
total service received: 0  realtime-service received: 0
transmitted: 0  dropped: 0  queue length: 0  period: 0
internal state - d: 0  e: 0  vt: 0  k: 0
 
 

C) in case of problems...

In case of problems the scheduler module can be loaded with a debug option which generates very extensive logging output via the syslog deamon:

illiac:~ # tc qdisc del dev eth1 root
illiac:~ # rmmod sch_hfsc
illiac:~ # insmod sch_hfsc hfsc_debug=100
Using /lib/modules/2.4.13/kernel/net/sched/sch_hfsc.o

/var/log/messages:

Nov  5 23:38:17 illiac kernel: ->init_module (sch_hfsc.c: line 3429)
Nov  5 23:38:17 illiac kernel: Hierarchical Fair Service Curve Scheduler (H-FSC) [Oct 31 2001 18:45:57]
Nov  5 23:38:17 illiac kernel: H-FSC: -- compiled with wireless scheduling extensions --
Nov  5 23:38:17 illiac kernel: H-FSC: --        compiled with debugging support       --
Nov  5 23:38:17 illiac kernel: <-init_module (sch_hfsc.c: line 3441)

illiac:~ # insmod wchmon_driver
Using /lib/modules/2.4.13/kernel/net/sched/wchmon_driver.o

illiac:~ # cp lucent_avaya_10_8.cnf /proc/net/wchmon_gtr_map

illiac:~ # tc qdisc add dev eth1 root handle 10:0 hfsc bandwidth 5Mbit wireless
wchmon driver reducebad 100

The output in /var/log/messages will look like:

Nov  5 23:39:49 illiac kernel: ->hfsc_init (sch_hfsc.c: line 287)
Nov  5 23:39:49 illiac kernel: ->ellist_alloc (sch_hfsc.c: line 1626)
Nov  5 23:39:49 illiac kernel: <-ellist_alloc (sch_hfsc.c: line 1633)
Nov  5 23:39:49 illiac kernel: ->hfsc_class_create (sch_hfsc.c: line 462)
Nov  5 23:39:49 illiac kernel: <-hfsc_class_create (sch_hfsc.c: line 627)
Nov  5 23:39:49 illiac kernel: <-hfsc_init (sch_hfsc.c: line 370)
Nov  5 23:39:49 illiac kernel: ->hfsc_dump (sch_hfsc.c: line 3327)
Nov  5 23:39:49 illiac kernel: <-hfsc_dump (sch_hfsc.c: line 3330)

Next we enqueue and dequeue a packet.:

Nov  5 23:44:35 illiac kernel: ->hfsc_enqueue (sch_hfsc.c: line 937)
Nov  5 23:44:35 illiac kernel: hfsc_enqueue: packet for default class
Nov  5 23:44:35 illiac kernel: ->set_active (sch_hfsc.c: line 1338)
Nov  5 23:44:35 illiac kernel: ->dfactor_rt_service_estimate (sch_hfsc.c: line 2201)
Nov  5 23:44:35 illiac kernel: wchmon returned channel capacity of 553395 byte/s
Nov  5 23:44:35 illiac kernel: RT Service 42 for packet length 42.
Nov  5 23:44:35 illiac kernel: <-dfactor_rt_service_estimate (sch_hfsc.c: line 2242)
Nov  5 23:44:35 illiac kernel: ->init_ed (sch_hfsc.c: line 1440)
Nov  5 23:44:35 illiac kernel: time: 881659531850
Nov  5 23:44:35 illiac kernel: <-init_ed (sch_hfsc.c: line 1462)
Nov  5 23:44:35 illiac kernel: ->dfactor_vt_service_estimate (sch_hfsc.c: line 2261)
Nov  5 23:44:35 illiac kernel: wchmon returned channel capacity of 553395 byte/s
Nov  5 23:44:35 illiac kernel: VT Service 49 for packet length 42.
Nov  5 23:44:35 illiac kernel: <-dfactor_vt_service_estimate (sch_hfsc.c: line 2289)
Nov  5 23:44:35 illiac kernel: ->init_v (sch_hfsc.c: line 1527)
Nov  5 23:44:35 illiac kernel: <-init_v (sch_hfsc.c: line 1567)
Nov  5 23:44:35 illiac kernel: ->dfactor_add_curve (sch_hfsc.c: line 2365)
Nov  5 23:44:35 illiac kernel: <-dfactor_add_curve (sch_hfsc.c: line 2443)
Nov  5 23:44:35 illiac kernel: <-set_active (sch_hfsc.c: line 1390)
Nov  5 23:44:35 illiac kernel: <-hfsc_enqueue (sch_hfsc.c: line 1000)
Nov  5 23:44:35 illiac kernel: ->hfsc_dequeue (sch_hfsc.c: line 1023)
Nov  5 23:44:35 illiac kernel: time: 881659532032
Nov  5 23:44:35 illiac kernel: ->dfactor_vt_service_estimate (sch_hfsc.c: line 2261)
Nov  5 23:44:35 illiac kernel: wchmon returned channel capacity of 553395 byte/s
Nov  5 23:44:35 illiac kernel: VT Service 49 for packet length 42.
Nov  5 23:44:35 illiac kernel: <-dfactor_vt_service_estimate (sch_hfsc.c: line 2289)
Nov  5 23:44:35 illiac kernel: ->update_v (sch_hfsc.c: line 1578)
Nov  5 23:44:35 illiac kernel: <-update_v (sch_hfsc.c: line 1607)
Nov  5 23:44:35 illiac kernel: ->dfactor_rt_service_estimate (sch_hfsc.c: line 2201)
Nov  5 23:44:35 illiac kernel: wchmon returned channel capacity of 553395 byte/s
Nov  5 23:44:35 illiac kernel: RT Service 48 for packet length 42.
Nov  5 23:44:35 illiac kernel: <-dfactor_rt_service_estimate (sch_hfsc.c: line 2242)
Nov  5 23:44:35 illiac kernel: ->set_passive (sch_hfsc.c: line 1400)
Nov  5 23:44:35 illiac kernel: ->dfactor_remove_curve (sch_hfsc.c: line 2454)
Nov  5 23:44:35 illiac kernel: <-dfactor_remove_curve (sch_hfsc.c: line 2528)
Nov  5 23:44:35 illiac kernel: <-set_passive (sch_hfsc.c: line 1429)
Nov  5 23:44:35 illiac kernel: <-hfsc_dequeue (sch_hfsc.c: line 1243)
 

Using this method one can follow exactly the different decisions the scheduler makes at each point in time. The level at which debugging output is generated can be toggled - for more information see the comments in the sch_hfsc.c sources and the technical documentation available on the project web site.