Title: Fair Internet bandwidth management on a network using Linux
       Author: Solène
       Date: 05 August 2022
       Tags: linux bandwidth qos
       Description: This article introduce you to network quality of service
       to make a router fairly assigning bandwidth to network consumers on
       your LAN.
       
       # Introduction
       
       A while ago I wrote an OpenBSD guide to fairly share the Internet
       bandwidth to the LAN network, it was more or less working.  Now I
       switched my router to Linux, I wanted to achieve the same. 
       Unfortunately, it's not really documented as well as on OpenBSD.
       
       The command needed for this job is "tc", acronym for Traffic Control,
       the Jack of all trades when it comes to manipulate your network
       traffic.  It can add delays or packets lost (this is fun when you want
       to simulate poor conditions), but also traffic shaping and Quality of
       Service (QoS).
       
 (HTM) Wikipedia page about tc
       
       Fortunately, tc is not that complicated for what we will achieve in
       this how-to (fair share) and will give results way better than what I
       achieved with OpenBSD!
       
       # How it works
       
       I don't want to explain how the whole stack involved works, but with tc
       we will define a queue on the interface we want to apply the QoS, it
       will create a number of flows assigned to each active network streams,
       each active flow will receive 1/total_active_flows shares of bandwidth.
        It mean if you have three connections downloading data (from the same
       computer or three different computers), they should in theory receive
       1/3 of bandwidth each.  In practice, you don't get exactly that, but
       it's quite close.
       
       # Setup
       
       I made a script with variables to make it easy to reuse, it deletes any
       traffic control set on the interfaces and then creates the
       configuration.  You are supposed to run it at boot.
       
       It contains two variables, DOWNLOAD_LIMIT and UPLOAD_LIMIT that should
       be approximately 95% of each maximum speed, it can be defined in bits
       with kbits/mbits or in bytes with kbps/mbps, the reason to use 95% is
       to let the router some room for organizing the packets.  It's like a
       "15 puzzle", you need one empty square to use it.
       
       ```sh
       #!/bin/sh
       
       TC=$(which tc)
       
       # LAN interface on which you have NAT
       LAN_IF=br0
       
       # WAN interface which connects to the Internet
       WAN_IF=eth0
       
       # 95% of maximum download
       DOWNLOAD_LIMIT=13110kbit
       
       # 95% of maximum upload
       UPLOAD_LIMIT=840kbit
       
       $TC qdisc del dev $LAN_IF root
       $TC qdisc del dev $WAN_IF root
       
       $TC qdisc add dev $WAN_IF root handle 1: htb default 1
       $TC class add dev $WAN_IF parent 1: classid 1:1 htb rate $UPLOAD_LIMIT
       $TC qdisc add dev $WAN_IF parent 1:1 fq_codel noecn
       
       $TC qdisc add dev $LAN_IF root handle 1: htb default 1
       $TC class add dev $LAN_IF parent 1: classid 1:1 htb rate $DOWNLOAD_LIMIT
       $TC qdisc add dev $LAN_IF parent 1:1 fq_codel
       ```
       
       # Conclusion
       
       tc is very effective but not really straightfoward to understand. 
       What's cool is you can apply it on the fly without incidence.
       
       It has been really effective for me, now if some device is downloading
       on the network, it doesn't affect much the other devices when they need
       to reach the Internet.
       
       # Credits
       
       After lurking on the Internet looking for documentation about tc, I
       finally found someone who made a clear explanation about this tool.  tc
       is documented, but it's too abstract for me.
       
 (HTM) linux home router traffic shaping with fq_codel