## QOS Configuration

### Tom Eastep

Copyright © 2012, 2020 Thomas M. Eastep

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.

2026/01/29

## Introduction

This configuration was inspired by the one in this thread on the OpenWRT Forum: https://forum.openwrt.org/viewtopic.php?pid=154533#p154533. The configuration has been adapted to Shorewall 4.5.6 with the following changes:

1. The configuration uses an IFB, yet only uses firewall marks in the OUTPUT and FORWARD chains to classify packets; clearly that doesn't work[1]The configuration presented here uses U32 classifiers (shorewall-tcfilters(5)) to classify traffic for download shaping and uses the POSTROUTING chain for upload shaping.

2. The sample uses a weak form of P2P classification; the one presented below uses IPP2P.

3. The OpenWRT script assumed that the uplink was ATM -- the one below makes no assumption (it specifies 'ethernet' with overhead '0').

## /etc/shorewall/params

The shell variables set in the OpenWRT script are set in the Shorewall params file:

    # local network

    MYNET=192.168.0.0/24

    DOWNLOAD=40000 #download speed in kbit. set xx% of real download speed
    UPLOAD=7000 # set xx% of real upload speed

    # multiports = up to 15 ports
    # ports to be classified as bulk #set after connection mark save and after connection mark restore
    TCP_BULK="1024:" #S and D ports
    UDP_BULK="1024:" #S and D ports

    # Destination ports to be classified as P2P
    TCP_P2P="13769" #D ports
    UDP_P2P="13769" #D ports
    IP_P2P="192.168.0.133"

    # Destination ports to be classified as normal
    TCP_NORMAL="80,443,25,20,21,110,993,995" # D ports
    UDP_NORMAL=""

    # Destination ports to be classified as Prio (overules bulk ports)
    TCP_PRIO="22,53" #destination ports
    UDP_PRIO="22,53" #destination ports

    # Destination ports to be classified as VoIP (overules bulk ports)
    TCP_VOIP=""
    UDP_VOIP="18080"
    IP_VOIP="192.168.0.226" #destination and source IP
    IP_VOIP="192.168.0.226" #destination and source IP

    #!!!!!uplink leaf class parameters!!!!!!!!!

    #bulk
    UP_LS_BULK_RATE=$(($UPLOAD*5/100))
    UP_UL_BULK_RATE=$UPLOAD
    #settings leaf qdisc
    UP_BULK_RED_PROB=0.05 #red drob probability
    UP_BULK_RED_min=6250 #real limit. To limit BULK traffic
    UP_BULK_RED_min2=6250 #min for doing the calculations (burst and etc)
    UP_BULK_RED_max=$((2 * $UP_BULK_RED_min2 + $UP_BULK_RED_min))
    UP_BULK_RED_burst=$(((5 * $UP_BULK_RED_min2) / (3 * 1000)))
    UP_BULK_RED_limit=$(($UP_BULK_RED_max * 5))

    #P2P
    UP_LS_P2P_RATE=$(($UPLOAD * 5 / 100))
    UP_UL_P2P_RATE=$UPLOAD
    #settings leaf qdisc
    UP_P2P_RED_PROB=0.05 #red drob probability
    UP_P2P_RED_min=32000 #real limit. To limit P2P traffic
    UP_P2P_RED_min2=32000 #min for doing the calculations (burst and etc)
    UP_P2P_RED_max=$((5 * $UP_P2P_RED_min2 + $UP_P2P_RED_min))
    UP_P2P_RED_burst=$(((5 * $UP_P2P_RED_min2) / (3 * 1000)))
    UP_P2P_RED_limit=$(($UP_P2P_RED_max * 5))
    #normal class
    UP_LS_NORMAL_RATE=$(($UPLOAD * 40 / 100))
    UP_UL_NORMAL_RATE=$UPLOAD
    #settings leaf qdisc
    UP_NORMAL_RED_PROB=0.05 #red drob probability
    UP_NORMAL_RED_min=6250 #real limit. To limit NORMAL traffic
    UP_NORMAL_RED_min2=6250 #min for doing the calculations (burst and etc)
    UP_NORMAL_RED_max=$((2 * $UP_NORMAL_RED_min2 + $UP_NORMAL_RED_min))
    UP_NORMAL_RED_burst=$(((5 * $UP_NORMAL_RED_min2) / (3 * 1000)))
    UP_NORMAL_RED_limit=$(($UP_NORMAL_RED_max * 5))

    #prio
    UP_LS_PRIO_RATE=$(($UPLOAD*50/100))
    UP_RT_PRIO_RATE="200" #rate in kbit
    UP_RT_PRIO_UMAX="400" #lengte of the packets [byte]
    UP_RT_PRIO_DMAX="15" #delay in ms
    UP_UL_PRIO_RATE=$UPLOAD

    #Voip
    UP_UL_VOIP_RATE=$UPLOAD
    UP_SC_VOIP_RATE="200"
    UP_SC_VOIP_UMAX="350" #length of the voip packets [byte]
    UP_SC_VOIP_DMAX="10" #delay in ms

    #bulk
    DOWN_LS_BULK_RATE=$(($DOWNLOAD*5/100))
    DOWN_UL_BULK_RATE=$DOWNLOAD
    #leaf qdisc parameters
    DOWN_BULK_RED_PROB=0.05 #red drob probability
    DOWN_BULK_RED_min=62500 #real limit. To limit BULK traffic
    DOWN_BULK_RED_min2=62500 #min for doing the calculations (burst and etc)
    DOWN_BULK_RED_max=$((2 * $DOWN_BULK_RED_min2 + $DOWN_BULK_RED_min))
    DOWN_BULK_RED_burst=$(((5 * $DOWN_BULK_RED_min2) / (3 * 1000)))
    DOWN_BULK_RED_limit=$(($DOWN_BULK_RED_max * 5))

    #P2P
    DOWN_LS_P2P_RATE=$(($DOWNLOAD*5/100))
    DOWN_UL_P2P_RATE=4000
    #leaf qdisc parameters
    DOWN_P2P_RED_PROB=0.05 #red drob probability
    DOWN_P2P_RED_min=200000 #real limit. To limit P2P traffic
    DOWN_P2P_RED_min2=200000 #min for doing the calculations (burst and etc)
    DOWN_P2P_RED_max=$((2 * $DOWN_P2P_RED_min2 + $DOWN_P2P_RED_min))
    DOWN_P2P_RED_burst=$(((5 * $DOWN_P2P_RED_min2) / (3 * 1000)))
    DOWN_P2P_RED_limit=$(($DOWN_P2P_RED_max * 5))

    #normal class
    DOWN_LS_NORMAL_RATE=$(($DOWNLOAD*75/100))
    DOWN_UL_NORMAL_RATE=$DOWNLOAD

    #leaf qdisc parameters
    DOWN_NORMAL_RED_PROB=0.05 #red drob probability
    DOWN_NORMAL_RED_min=62500 #real limit. To limit NORMAL traffic
    DOWN_NORMAL_RED_min2=62500 #min for doing the calculations (burst and etc)
    DOWN_NORMAL_RED_max=$((2 * $DOWN_NORMAL_RED_min2 + $DOWN_NORMAL_RED_min))
    DOWN_NORMAL_RED_burst=$(((5 * $DOWN_NORMAL_RED_min2) / (3 * 1000)))
    DOWN_NORMAL_RED_limit=$(($DOWN_NORMAL_RED_max * 5))

    #prio
    DOWN_RT_PRIO_RATE="500" #rate in kbit
    DOWN_RT_PRIO_UMAX="400" #length of the packets [byte]/
    DOWN_RT_PRIO_DMAX="1.5" #delay in ms
    DOWN_UL_PRIO_RATE=$DOWNLOAD

    #Voip
    DOWN_UL_VOIP_RATE=$DOWNLOAD
    DOWN_SC_VOIP_RATE="250"
    DOWN_SC_VOIP_UMAX="350" #lengt of voip packets [byte]
    DOWN_SC_VOIP_DMAX="1.2" #delay in ms

## /etc/shorewall/init

The init file loads the ifb module, creating a single device:

    modprobe ifb numifbs=1
    ip link set ifb0 up

## /etc/shorewall/tcdevices

The tcdevices file describes the two devices:

    #NUMBER:        IN_BANDWITH     OUT_BANDWIDTH   OPTIONS         REDIRECT
    1:eth0          -               ${UPLOAD}kbit   hfsc,linklayer=ethernet,overhead=0
    2:ifb0          -               ${DOWNLOAD}kbit hfsc            eth0

## /etc/shorewall/tcclasses

The tcclasses file defines the class hierarchy for both devices:

    #INTERFACE MARK    RATE                            CEIL                            PRIORITY        OPTIONS
    1          1       ${UP_SC_VOIP_RATE}kbit:\
                       ${UP_SC_VOIP_DMAX}:\
                       ${UP_SC_VOIP_UMAX}              ${UP_UL_VOIP_RATE}kbit          1

    1          2       ${UP_RT_PRIO_RATE}kbit:\
                       ${UP_RT_PRIO_DMAX}:\
                       ${UP_RT_PRIO_UMAX}              ${UP_LS_PRIO_RATE}kbit:\
                                                       ${UP_UL_PRIO_RATE}kbit          1

    1          3       -                               ${UP_LS_NORMAL_RATE}kbit:\
                                                       ${UP_UL_NORMAL_RATE}kbit        1               red=(limit=$UP_NORMAL_RED_limit,\
                                                                                                            min=$UP_NORMAL_RED_min,\
                                                                                                            max=$UP_NORMAL_RED_max,\
                                                                                                            burst=$UP_NORMAL_RED_burst,\
                                                                                                            probability=$UP_NORMAL_RED_PROB,\
                                                                                                            ecn)
    1          4       -                               ${UP_LS_P2P_RATE}kbit:\
                                                       ${UP_UL_P2P_RATE}kbit           1               red=(limit=$UP_P2P_RED_limit,\
                                                                                                            min=$UP_P2P_RED_min,\
                                                                                                            max=$UP_P2P_RED_max,\
                                                                                                            burst=$UP_P2P_RED_burst,\
                                                                                                            probability=$UP_P2P_RED_PROB,\
                                                                                                            ecn)
    1          5       -                               ${UP_LS_BULK_RATE}kbit:\
                                                       ${UP_UL_BULK_RATE}kbit          1               default,\
                                                                                                       red=(limit=$UP_BULK_RED_limit,\
                                                                                                            min=$UP_BULK_RED_min,\
                                                                                                            max=$UP_BULK_RED_max,\
                                                                                                            burst=$UP_BULK_RED_burst,\
                                                                                                            probability=$UP_BULK_RED_PROB,\
                                                                                                            ecn)

    2:10       -       ${UP_SC_VOIP_RATE}kbit:\
                       ${UP_SC_VOIP_DMAX}:\
                       ${UP_SC_VOIP_UMAX}              ${UP_UL_VOIP_RATE}kbit          1

    2:20       -       ${DOWN_RT_PRIO_RATE}kbit:\
                       ${DOWN_RT_PRIO_DMAX}:\
                       ${DOWN_RT_PRIO_UMAX}            ${DOWN_UL_PRIO_RATE}kbit        1

    2:30       -       -                               ${DOWN_LS_NORMAL_RATE}kbit:\
                                                       ${DOWN_UL_NORMAL_RATE}kbit      1               red=(limit=$DOWN_NORMAL_RED_limit,\
                                                                                                            min=$DOWN_NORMAL_RED_min,\
                                                                                                            max=$DOWN_NORMAL_RED_max,\
                                                                                                            burst=$DOWN_NORMAL_RED_burst,\
                                                                                                            probability=$DOWN_NORMAL_RED_PROB)
    2:40       -       -                               ${DOWN_LS_P2P_RATE}kbit:\
                                                       ${DOWN_UL_P2P_RATE}kbit         1               red=(limit=$DOWN_P2P_RED_limit,\
                                                                                                            min=$DOWN_P2P_RED_min,\
                                                                                                            max=$DOWN_P2P_RED_max,\
                                                                                                            burst=$DOWN_P2P_RED_burst,\
                                                                                                            probability=$DOWN_P2P_RED_PROB)
    2:50       -       -                               ${DOWN_LS_BULK_RATE}kbit:\
                                                       ${DOWN_UL_BULK_RATE}kbit        1               default,\
                                                                                                       red=(limit=$DOWN_BULK_RED_limit,\
                                                                                                            min=$DOWN_BULK_RED_min,\
                                                                                                            max=$DOWN_BULK_RED_max,\
                                                                                                            burst=$DOWN_BULK_RED_burst,\
                                                                                                            probability=$DOWN_BULK_RED_PROB)

## /etc/shorewall/mangle

The mangle file classifies upload packets:

    #ACTION          SOURCE         DEST          PROTO     DPORT       SPORT      USER    TEST
    RESTORE:T        -              -             -         -           -          -       !0:C
    CONTINUE:T       -              -             -         -           -          -       !0
    MARK(2):T        -              -             icmp
    MARK(1):T        -              -             udp       $UDP_VOIP   -          -       0
    MARK(1):T        $IP_VOIP       -             -         -           -          -       0
    MARK(1):T        -              $IP_VOIP      -         -           -          -       0
    MARK(2):T        -              -             tcp       $TCP_PRIO   -          -       0
    MARK(2):T        -              -             udp       $UDP_PRIO   -          -       0
    MARK(2):T        -              -             tcp       -           $TCP_PRIO  -       0
    MARK(2):T        -              -             udp       -           $UDP_PRIO  -       0
    MARK(3):T        -              -             tcp       $TCP_NORMAL -          -       0
    MARK(4):T        -              -             ipp2p:all -           -          -       0
    MARK(5):T        -              -             tcp       $TCP_BULK   -          -       0
    MARK(5):T        -              -             tcp       -           $TCP_BULK  -       0
    MARK(5):T        -              -             udp       $UDP_BULK   -          -       0
    MARK(5):T        -              -             udp       -           $UDP_BULK  -       0
    SAVE:T           -              -             -         -           -          -      !0

## /etc/shorewall/tcfilters

The tcfilters file classifies download packets:

    #INTERFACE:     SOURCE  DEST    PROTO   DPORT   SPORT     TOS            LENGTH
    #
    # These classify download traffic
    #
    2:10            -       $MYNET  udp     -       $UDP_VOIP
    2:20            -       $MYNET  tcp     -       $TCP_PRIO
    2:20            -       $MYNET  udp     -       $UDP_PRIO
    2:20            -       $MYNET  tcp     $TCP_PRIO
    2:20            -       $MYNET  udp     $UDP_PRIO
    2:30            -       $MYNET  tcp     -       $TCP_NORMAL
    2:50            -       $MYNET  tcp     $TCP_BULK
    2:50            -       $MYNET  tcp     -       $TCP_BULK
    2:50            -       $MYNET  udp     $UDP_BULK
    2:50            -       $MYNET  tcp     -       $UDP_BULK

[1] To be more precise, it doesn't work with an unpatched kernel. The OpenWRT script assumes an 'act_conntrack' patch which performs conntrack processing on packets before they are sent to the IFB. That patch is not generally available.