User Tools

Site Tools


doc:howto:packet.scheduler:packet.scheduler.example4

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
doc:howto:packet.scheduler:packet.scheduler.example4 [2012/09/12 00:29]
champtar Other end
doc:howto:packet.scheduler:packet.scheduler.example4 [2016/01/17 10:37] (current)
valentt
Line 1: Line 1:
 +====== Example4: HFSC + FQ_CODEL + FLOW classifier; ======
 +===== Basic ip-based fair sharing behind triple play box =====
  
 +
 +In this exemple the router is not connected directly to internet, but throught another router (triple play box for exemple, with adsl connection).
 +For fq_codel to work, we have to own the queue, ie the queue of packets has to be in the "​ROUTER",​ and not in the "​triple play box" (we can reorder packets only if we have multiple packets at a time).
 +As the link between the "​ROUTER"​ and the "​triple play box" is way bigger than the adsl connection (100mbits vs 1mbits up), we have to rate limit "​ROUTER"​ wan egress. We steel want to have the full speed when we access the "​triple play box" or the "tv box".
 +To finish we just want fair sharing based on source ip (even with nat activated on "​ROUTER"​).
 +
 +<​code>​
 +                                                                                ____
 +User 1==============\ ​         [tv box]===\ ​                                ​___( ​   )__
 +                     ​\ ​                    ​\ ​                             _(           )_
 +User 2===============[ROUTER]=============[triple play box]··············(_ ​ internet ​ __)
 +                     / ​                                                    ​(_ ​      __)
 +User n==============/ ​                                                       (______)
 +      LAN_SUBNET ​              ​WAN_SUBNET ​                    ​REAL_WAN
 +
 +</​code>​
 +
 +
 +<code bash>
 +#!/bin/sh /​etc/​rc.common
 +#
 +# License GPLv2
 +# Version 0.1
 +
 +START=99
 +EXTRA_COMMANDS="​status"​
 +
 +##############################################################​
 +# Variables
 +IF_WAN="​br-wan"​ #-- wan interface
 +WAN_NET="​192.168.1.0/​24"​ #-- wan local subnet
 +UP_RATE=900 #-- 90% of internet upload bandwidth in kilobits/​sec
 +PHY_RATE=90 #-- 90% of wan phy bandwidth in megabits/​sec
 +TC=/​usr/​sbin/​tc #-- location of traffic control
 +
 +MODULES='​sch_hfsc sch_ingress sch_fq_codel cls_flow cls_u32'​
 +
 +##############################################################​
 +status() {
 + echo "### Statistics ###"
 + echo "# qdiscs #"
 + tc -s qdisc show dev $IF_WAN
 + echo "# class #"
 + tc -s class show dev $IF_WAN
 +
 + echo "# filter #"
 + tc -s filter show dev $IF_WAN root
 + tc -s filter show dev $IF_WAN parent 1:
 + tc -s filter show dev $IF_WAN parent 11:
 +}
 +##############################################################​
 +
 +
 +
 +##############################################################​
 +stop() {
 + # Delete existing qdiscs (hide errors)
 + $TC qdisc del dev $IF_WAN root    2> /dev/null > /dev/null
 + $TC qdisc del dev $IF_WAN ingress 2> /dev/null > /dev/null
 +
 + # Unload modules
 + for i in $MODULES ; do
 + rmmod $i
 + done
 +}
 +##############################################################​
 +
 +
 +
 +###############################################################################​
 +start() {
 +# Load modules
 +for i in $MODULES ; do
 + insmod $i
 +done
 +
 +ifconfig $IF_WAN txqueuelen 1000
 +
 +# reset qdiscs
 +$TC qdisc del dev $IF_WAN root    2> /dev/null > /dev/null
 +$TC qdisc del dev $IF_WAN ingress 2> /dev/null > /dev/null
 +
 +
 +###############################################################################​
 +$TC qdisc add dev $IF_WAN root       ​handle ​ 1   hfsc default 1
 +
 +$TC class add dev $IF_WAN parent 1:  classid 1:1  hfsc sc rate ${UP_RATE}kbit ul rate ${UP_RATE}kbit
 +$TC qdisc add dev $IF_WAN parent 1:1 handle 11: fq_codel
 +$TC filter add dev $IF_WAN parent 11: handle 11 protocol all flow hash keys nfct-src divisor 1024
 +
 +$TC class add dev $IF_WAN parent 1:  classid 1:2  hfsc sc rate ${PHY_RATE}mbit ul rate ${PHY_RATE}mbit
 +$TC filter add dev $IF_WAN parent 1: protocol ip prio 1 u32 match ip dst ${WAN_NET} flowid 1:2
 +$TC filter add dev $IF_WAN parent 1: protocol arp prio 2 u32 match u32 0 0 flowid 1:2
 +}
 +</​code>​
 +
 +What we do:
 +  - Load kernel modules (will need HFSC / FQ_CODEL / INGRESS qdiscs, and FLOW / U32 classifiers) ​
 +  - Set the tx queue lengh. By default virtual iface (bridges (br-*), vlans (eth0.*)) txqueuelen is set to 0, and the qdisc inherit this value. QOS is about changing the queue (reordering,​ dropping), so if you have 0 packet in your queue ...
 +  - We add hfsc qdisc to the device ($IF_WAN), with handle X (1), and set default to Y (1 also), so every packet that isn't match by a filter will go to the class X:Y (1:1 here). The default behavior of HFSC is to drop packets that aren't classified, so it's safer to use default.
 +  - We add an hfsc class with classid X:1 (X = 1) to the qdisc with handle X (parent X: or parent 1: in our case). This class will rate limit the traffic to internet. This is the class that will get all the traffic not match be any filter (still following).
 +  - We add an fq_codel qdisc to the 1:1 hfsc class. His name will be 11 or 11: or 11:0 (handle 11, but we could have chosen 42)
 +  - We add a filter to the fq_codel to put each packet in a class (dynamic ...) based on his src ip address before NATing (nfct-src). To be more precise we hash nfct-src modulo "​divisor"​ (1024) and with this hash we decide in which fq_codel class we put the packet.
 +  - To finish we create another hfsc class for the WAN_SUBNET (hi-speed) traffic, and we filter in it all the IP packets with ${WAN_NET} destination (192.168.1.0/​24),​ and all the ARP packets.
 +
 +
 +===== Other end =====
 +
 +<code bash>
 +$TC qdisc add dev $IF_WAN root       ​handle ​ 1   hfsc default 2
 +
 +$TC class add dev $IF_WAN parent 1:  classid 1:1  hfsc sc rate ${UP_RATE}kbit ul rate ${UP_RATE}kbit
 +$TC qdisc add dev $IF_WAN parent 1:1 handle 11: fq_codel
 +$TC filter add dev $IF_WAN parent 11: handle 11 protocol all flow hash keys nfct-src divisor 1024
 +
 +$TC class add dev $IF_WAN parent 1:  classid 1:2  hfsc sc rate ${PHY_RATE}mbit ul rate ${PHY_RATE}mbit
 +$TC filter add dev $IF_WAN parent 1: protocol ip prio 1 u32 match ip dst ${WAN_NET} flowid 1:2 # match all local ip traffic
 +$TC filter add dev $IF_WAN parent 1: protocol ip prio 1 u32 match ip dst 255.255.255.255/​32 flowid 1:2 # Limited Broadcast
 +#$TC filter add dev $IF_WAN parent 1: protocol ip prio 1 u32 match ip dst 169.254.0.0/​16 flowid 1:2 # link-local
 +#$TC filter add dev $IF_WAN parent 1: protocol ip prio 1 u32 match ip dst 224.0.0.0/4 flowid 1:2 # multicast
 +
 +$TC filter add dev $IF_WAN parent 1: protocol ip prio 2 u32 match u32 0 0 flowid 1:1 # match all the remaining ip traffic
 +
 +#$TC filter add dev $IF_WAN parent 1: protocol all prio 3 u32 match u32 0 0 flowid 1:2 # useless as we use default 2
 +</​code>​
 +
 +{{tag>​qos}}